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
    CounterWeb.Endpoint.subscribe(@topic)
    Presence.track(
      self(),
      @topic,
      remote_ip |> :inet.ntoa(),
      %{
        online_at: inspect(System.system_time(:second))
      }
    )
    counter_value = Counter.value()
    {:ok,
      socket
      |> assign(:counter_value, counter_value)
      |> assign(:presence_list, Presence.list(@topic))
    }
  end


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
  end

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

I’ve pushed my app to Gigalixir so when I navigate to the page I expect to see what I see on ipapi.co/ip but instead I see an IPv6 (something like ::ffff:10.8.3.15) 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.

5 Likes

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