IP addresses from users?

Hey there, is there a function in phoenix where I can get the users ip address? I’d like to build a clone of whatsmyip

1 Like

Conn.remote_ip will give you the goods.

Also recommend you use remote_ip | Hex

6 Likes

You should inspect conn, because You can get ip from multiple attributes.

remote_ip, as mentionned in the previous response, but also x-forwarded-for, x-real-ip

1 Like

But these are just good old HTTP headers. Everyone can proxy through a VPS and spoof the headers so they frame somebody else’s IP.

I wouldn’t use them unless they can be cryptographically verified to come from they’re claiming to come.

1 Like

Yes it can be spoofed, but I meant relying on remote_ip only might give You the address of a proxy :slight_smile:

2 Likes

so when the user enters I page, I do something like conn.send_resp(200, “…”), how can I display the users IP there? instead of the string message just put conn in there? or bind it to a variable and use that instead?

Maybe like this to debug the conn…

You might also check if You use a proxy in front of the application.

conn.send_resp(200, inspect conn)

Get the IP as mentioned above, convert it to a string and send it.

2 things.

  1. Are you using a LiveView or a simple Controller+Template? If using a LiveView, you should copy the remote_ip from conn to socket assigns.

  2. Are you going to deploy this? Depending on what deployment service you use (Fly, Gigalixir, Heroku, etc) you might need to find the IP address some other way. Often these services see conn.remote_ip as something in their private network, but the real public IP of the request will be in some special header. For example, Fly uses "Fly-Client-IP.

1 Like

yea fly, most likely, how do I have to do that then?

Well, a nice simple way is:

  1. add remote_ip to your deps

  2. mix deps.get

  3. Add this to your endpoint.ex module:

 plug RemoteIp, headers: ["fly-client-ip"]

Update: if you’re using live view, you will have to get this remote IP from the conn into your socket assigns. If that doesn’t make sense to you, then you need to read about the on_mount function in LiveView. That will be your friend for this job.
here: Phoenix.LiveView — Phoenix LiveView v0.18.2

4 Likes

I think that the following post is a must-read, especially for the project in question:

The perils of the ‘real’ client IP

3 Likes

One question, wouldn’t the live view peer data solve it?
https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#get_connect_info/2-examples

I currently have an application on google cloud run, but my socket.assigns.peer_data.address is returning an IP from the internal network ex: 169.169.1.1

How would you get the user’s real IP?

I even found something here Cloud Run Client Request IP address gets overridden by proxy Python Fast API - Stack Overflow, saying to change the code to return the X-Forwarded-For?

Has anyone ever experienced this?

I was able to identify a cause.

I was getting the wrong key.

In case I need to get the x_headers

The problem is that every proxy in front does its own magic and there is no real “standard”. And you could (theoretically) have multiple layers of proxies in front. RemoteIp tries the common cases for you so you don’t have to go nuts, but it’s not 100% bullet-proof. In general, if you see anything strange, you have to dump conn and see what’s in there.