Phoenix socket/channels security / IP identification

I want to offer some free functionality on my site to unauthenticated users and need to limit & protect it from abuse (IP logging being crucial). Doing it via API requests is easy(conn.remote_ip) but can’t find anything similar for sockets.

Is it possible to get IP from socket/channel connections? Any examples?

If you have authenticated and unauthenticated, you have a token which you can use. Is there any specific reason you (only) want to use an ip address?

at this time you can’t. You can’t access the connection in channels because channels are transport agnostic (websocket, longpolling …), the straightforward solution is to pass the IP address as a parameter when connecting to the socket using some sort of ajax request to get the client IP

Phoenix 1.4 update:

Since Phoenix 1.4, you can get connection information from the underlying transport. What kind of information you get is transport dependent, but with the WebSocket transport it is possible to retrieve the peer info (ip address) and a list of x- headers (for x-forwarded-for resolving).

Configure your socket like this in your endpoint.ex:

  socket("/socket", MyApp.Web.UserSocket,
    websocket: [connect_info: [:peer_data, :x_headers]],
    longpoll: [connect_info: [:peer_data, :x_headers]]
  )

And then your UserSocket module must expose a connect/3 function like this:

  def connect(_params, socket, connect_info) do
    {:ok, socket}
  end

On connect, the connect_info parameter now contains info from the transport:

info: %{
  peer_data: %{address: {127, 0, 0, 1}, port: 52372, ssl_cert: nil},
  x_headers: []
}
13 Likes