How to display different UI if cookie exists or not in Phoenix LiveView

I want to be able to display different UI in a Phoenix LiveView depending on if a cookie is present or not, the cookie is being used to check if the user is signed in or not to display a sign in link or not. Within the existing model (without Phoenix LiveView) I’d create a Plug/Middleware assign the value to the connection and everything would work fine, however this approach doesn’t pass data through to the live view handlers.

Can someone help me understand a different approach I can take which works closely with the existing model, some examples or links to documentation would really be helpful to as I’m struggling to find anything that ties these pieces together.

Hopefully that makes sense, please let me know if you’d like some code examples.

Have a look at this section of the LiveView guides:

Security considerations of the LiveView model

There you can see that session is passed as the second param to the mount/3 callback. You should be able to use that to do what you need.

2 Likes

Thanks for the reply, really appreciate it! :slight_smile:

From the documentation it isn’t to clear where “user_id” in this example comes from, looking at the code I’m assuming it comes from the plugs :ensure_user_authenticated or :ensure_user_confirmed however I don’t know what they are doing in order to set this “user_id”.

After some digging I found you could use put_session, which allows me to send data to the live view. So my Plug/Middleware needs to look like this if I’m supporting both controllers and live views…

defmodule AppWeb.Plugs.Authenticated do
  @moduledoc false
  import Plug.Conn

  require Logger

  def init(default), do: default

  def call(conn, _default) do
    case get_authenticated_cookie(conn) do
      %{user_id: user_id} -> assign_authenticated_user(conn, user_id)
      _ -> assigned_unauthenticated_user(conn)
    end
  end

  defp get_authenticated_cookie(conn), do: ...

  defp assign_authenticated_user(conn, user_id) do
    Logger.debug("user is authenticated")
    conn
      |> put_session(:authenticated, true)
      |> put_session(:authenticated_user, user_id)
      |> assign(:authenticated, true)
      |> assign(:authenticated_user, user_id)
  end

  defp assigned_unauthenticated_user(conn) do
    Logger.debug("user is unauthenticated")
    conn
      |> put_session(:authenticated, false)
      |> assign(:authenticated, false)
  end
end

This works, its somewhat annoying that I have to write put_session and assign am I missing something that I can be doing better here?

Thanks again :slight_smile: