Hello, I have a Phoenix app running in Heroku, that uses force_ssl
as explained in the Heroku guides (configuring it on the Rocket.Endpoint for production).
This works fine, but for certain routes that listen for callbacks from other servers, I’d need to disable this SSL forcing. Because these other servers are having trouble handshaking our SSL cert or something.
Is there a way to force_ssl
in all the app, except for a few selected routes?
1 Like
It is a plug, so you can always wrap it in a plug to do a conditional check before including it.
Also, this exact question and possible work-arounds were discussed a while ago at: https://github.com/phoenixframework/phoenix/issues/1743 
Which the dev basically just says the same thing I did above, so that seems the best way to do it.
3 Likes
Thank you, I’ll try this. Not sure how to do that as it’s configured on the Endpoint, but it definitely points me to something 
1 Like
Ah, OK, got it working. I removed the force_ssl
option on the Endpoint, and instead plugged it on the browser pipeline in the Router, like this:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
if Mix.env == :prod do
plug Plug.SSL, rewrite_on: [:x_forwarded_proto]
plug :put_secure_browser_headers
end
end
And then, for the routes where I don’t want to enforce SSL, I have another pipeline where it isn’t enforced.
Easy peasy! Thanks!
5 Likes
Ahh that is a simple way of doing it! Thanks for the documentation on that. 
Yeah, I was confused because I was seeing force_ssl
as a config option on the Endpoint, and I forgot that it was a plug.
I’ve updated the example to show how to apply this only on the production environment.
1 Like
If you are using channels and you disabled the global config, you also may want to pass the force_ssl: true
option to your socket
calls in your endpoint.
3 Likes
Thanks, I’m using channels and would like to force ssl on them too - but I don’t see what you mean, in the endpoint the socket call only accepts path and module, how to pass the force_ssl: true
option?
https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#socket/2
I assume you’re talking about this socket
call?
defmodule MyApp.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
socket "/socket", MyApp.UserSocket
Sorry, you are right. The option should be given to each transport in your socket, so:
transport :websocket, Phoenix.Transports.WebSocket, force_ssl: true