How to show client's IPv4 on page?

I’ve got a LiveView app which basically has a counter on the page. I am also using Presence to track users so I would like to show the IPv4 of online users just for learning purposes.

Below you can see the mount/3 function implementation.

# counter_live.ex

  @topic "counter"

  @impl true
  def mount(_params, %{"remote_ip" => remote_ip} = session, socket) do
      remote_ip |> :inet.ntoa(),
        online_at: inspect(System.system_time(:second))
    counter_value = Counter.value()
      |> assign(:counter_value, counter_value)
      |> assign(:presence_list, Presence.list(@topic))

I’ve done what the answer below says to put the remote_ip into session.

# router.ex
  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, {CounterWeb.LayoutView, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug :put_client_ip

  defp put_client_ip(conn, _) do
    Plug.Conn.put_session(conn, :remote_ip, conn.remote_ip)

I’ve pushed my app to Gigalixir so when I navigate to the page I expect to see what I see on but instead I see an IPv6 (something like ::ffff: which changes with each request to the website and I do not really have any idea why it changes or why I see an IPv6. Could you please help me understand & fix this?

There are many fields with ip… if You are behind a proxy.

You should inspect your conn, and look for x-forwarded-for, or x-real-ip.

1 Like

By default, Plug puts the IP of the peer in conn.remote_ip. When running behind a load balancer, that will be the internal IP of the load balancer.

Gigalixir apps run behind a load balancer, so you need to use a Plug that understands how to parse X-Forwarded-For headers. I’ve used remote_ip before in production with no complaints (though the network was IPv4-only because old AWS gear). The motivation section of that README is a good place to learn more about the situation.


Thank you so much both! Just what I was looking for.