LiveView access to cookies

Hi, I’m using clerk.com for authentication (I wrote a thin API wrapper for server-side checks). I rely on conn |> Plug.Conn.fetch_cookies to pull this off.

In a LiveView, is there a way to access cookies? I only see the CSRF in my mount/3 session value. I can see the cookies are there in the browser request to open the socket connection, but I don’t see them in my LiveView.

Thank you!

Welcome!

How have you configured your Phoenix.Endpoint.socket/3?

This section of the socket/3 docs on specifying Connect info seems relevant.

1 Like

You need to extract what you want from the cookie and add it to the session. The session gets passed to LiveView in the mount/3 callback.

I do exactly this and it works fine.

Here’s my plug code:

defmodule MyWeb.Plug.PutUserFromCookie do
  @moduledoc """
  Reads a user_details cookie and puts user_details into session
  """
  import Plug.Conn

  def init(_) do
    %{}
  end

  def call(conn, _opts) do
    conn = fetch_cookies(conn)

    cookie = conn.cookies["user_cookie"]

    user_details = case cookie do
      nil -> 
        %{user_name: "Anonymous",  user_id: nil}
      _ ->
       Plug.Conn.Query.decode(cookie)
    end

    conn
    |> put_session(:user_details, user_details) # Makes it available in LiveView
    |> assign(:user_details, user_details) # Makes it available in traditional controllers etc
  end

end

This plug needs to be included in the router pipeline:

  pipeline :browser do
    plug :accepts, ["html", "json"]
    plug :fetch_session
    plug MyWeb.Plug.PutUserFromCookie # <-
    plug :fetch_live_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug :put_root_layout, {MyWeb.LayoutView, "root.html"}
  end

Then in your LiveView, your mount function would be something like:

  @impl true
  def mount(_params, session, socket) do
    user_details = session["user_details"]

    socket =
      socket
      |> assign(:user_details, user_details)
...

If you get sick of copying / pasting the code to transfer the user details from session to socket assigns in each and every LiveView, you can set up an on_mount hook

8 Likes

I’ll try this tonight. A huge thank you! New to Elixir + Phoenix. Not the steepest learning curve I’ve experienced certainly, but definitely getting tripped up on “simple” things.

1 Like

put_session/3 did the trick. Thanks again!

Hey @boiserunner, would you mind sharing the code you used to authenticate with clerk?

2 Likes

Hey! We are planning to release it as a community project hopefully this month. We are just in a pretty busy release cycle at the moment. I’ll report back when it’s ready to roll.

2 Likes

Hi @boiserunner , have you released it? If so, could you please share the GitHub link here?

I am trying to use Clerk in my backend API.
The documentation on clerk is not very clear to me.
I have implemented a JWT Auth using JOSE to verify the bearer token from the request header.
I am having trouble understanding the webhooks implementation.
Especially the part, bringing the user details to the database. Can anyone help with this?

I had to create a new endpoint which handles the info from clerk webhooks.
In the controller, I handled events based on the info received.
I ended up creating a plug for verifying the webhooks and used it for the endpoint route pipeline.