Sorc96

Sorc96

VerifiedRoutes.url used behind reverse proxy

I’ve encountered an issue with VerifiedRoutes.url when the application is running behind nginx. I need to send a link via e-mail, so I generate the url with url(~p/some_path/), which returns http://myapp.com:5000/some_path, since the endpoint itself is using http and the port is set to 5000. Of course, what I actually need is https://myapp.com/some_path

I have nginx configured to send the X-Forwarded-For header, so the application knows the actual address that is visible to users. Is there an easy way to make url use this information instead of the endpoint config? Or should I make a custom helper instead?

Marked As Solved

ibarch

ibarch

I haven’t tested it myself, but I guess that if you configure Nginx to pass the x-forwarded-port header, and apply Plug.RewriteOn plug in the endpoint, the url helpers will generate links with the appropriate port(s).

Also Liked

voltone

voltone

This configuration might fix the generated URLs, but it does not solve the underlying issue that Phoenix does not know that the server was actually reached via HTTPS. As a result, certain security features are not enabled. In particular, (session) cookies do not get the secure option that is meant to prevent them from leaking in plaintext HTTP requests.

For more details, see TLS Vulnerabilities | EEF Security WG

The better solution is the use of HTTP headers to pass the external scheme and port from the reverse proxy to the application, as suggested by @ibarch

garrison

garrison

The URL generation is controlled by the Endpoint configuration (specifically the :url option). The value is configured in runtime.exs by default. This option only controls URL generation (for links in the app), it does not configure the webserver (that’s the :http option right below it).

I’m assuming from your post that you changed it thinking it was the webserver configuration, so if that’s the case changing it back to the default should resolve the problem :slight_smile:

(Also: If this is the case, the links in your app should all be wrong too, right?)

For the record, you could also pass a few other things into url/2 if you needed to, like a conn / socket, a different endpoint, or a URI. But I don’t think that’s what you need here.

Not sure I understand what you mean here. X-Forwarded-For contains the original client IP address(es) from the original request (and any proxies in between). The host/port are sent via the Host header, which I assume Nginx just passes along in the proxied request.

Either way, by default the URL generation is controlled by the Endpoint config.

Sorc96

Sorc96

So I think the confusion has been explained. The scheme option worked as expected, but it seems that the port from the http config gets used for url generation as well, so I had to explicitly set it to 443. Thanks for the help, this is what the config looks like in case anyone else gets confused:

config :myapp, MyappWeb.Endpoint,
  url: [
    scheme: "https",
    host: "myapp.com",
    port: 443
  ],
  http: [port: 5000]

Also, to explain why I never noticed it from links in the application itself, it’s because they only need ~p unlike links in e-mails, which need the full url, so the incorrect options never manifested.

Where Next?

Popular in Questions Top

skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New

Other popular topics Top

New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

We're in Beta

About us Mission Statement