Phoenix channels over non-SSL

Hello everyone!

We’re building the seamless chat service Planga. (An official release will come soon! :smiley:)

Communication between the user’s browser with the other users is done through a Phoenix Channel (either using a websocket-connection or the fallback longpoll-transport).

Now, we’ve turned off CSRF-prevention checking, since any site is allowed to perform requests to the service (and it is then authenticated using their API key).

However, it seems that by default, Phoenix does not allow you to connect to websockets-over-ssl (wss:// as protocol) if the client application the user is visiting is a non-https website. The same is true for the longpoll transport (Phoenix disallows https://-based longpolling from a http website).

In development, where Phoenix runs without SSL itself, this is obviously not a problem, but since we’d like to allow developers that want to use our API to test things out with the system without them having to set up HTTPS certificates for their locally running development environments, we’d like to change this behaviour.

How can this behaviour be changed?

2 Likes

If I understand your issue correctly, this is not a phoenix thing, but a browser thing. Browsers will generally disallow mix content. For the phoenix.js client, if you leave off the protocol, it will inherit ws or wss based on the browser window’s protocol. Phoenix.js and the elixir channels side will gladly accept wss traffic. If you let the client inherit the protocol, ie let socket = new Socket("//yourhost.com/socket"). Provided your phoenix endpoint is configured for :http and :https then you are all set.

7 Likes

As I recall and that which a quick google search seems to confirm, an http page’s javascript can load wss websockets, but an https page’s javascript cannot load a ws websocket.

6 Likes

Thank you both!

What seems to be going on here is the following:

  1. I specify the socket location using the protocol-agnostic domain name "//example.com/socket".
  2. From an HTTP location, such as localhost, this makes the JS socket attempt to connect to http://example.com/socket/websocket?vsn=2.0 to set up ws://example.com/socket/websocket?vsn=2.0.
  3. However, Phoenix (or rather, Nginx running in front of it) currently disallows access to the site over non-SSL, so this connection is refused. (Or rather: A 301 to the HTTPS-variant is returned, which either is not supported by the phoenix_channel.js library, or by the browser’s websocket-connection-creation logic).

What would be the best way to resolve this? I’d rather have people on HTTP still try to connect to wss resp. https chats.

Why not just always do "wss://example.com/socket instead?

1 Like