This is basically correct. What I did in my app is create a %Context{}
struct which holds things like the current user. Then I setup this context for both plug and in my live view:
In my plug:
case Common.Sensetra.lookup_context(conn.host, org_id, token) do
{:error, :no_grant} ->
conn
|> redirect(to: "/")
|> halt
{:ok, ctx} ->
conn
|> assign(:context, ctx)
|> assign(:host, conn.host)
|> merge_assigns(assigns_from_context(ctx))
{:error, %{"errors" => _}} ->
conn
|> put_session(:token, nil)
|> redirect(to: "/")
|> halt()
end
In my live view:
# elsewhere
import CommonWeb.Socket
# then
def mount(params, session, socket) do
socket = init_assigns(params, session, socket)
defmodule CommonWeb.Socket do
import Phoenix.LiveView
@doc """
This initializes the socket assigns
"""
def init_assigns(params, session, %Phoenix.LiveView.Socket{} = socket) do
%{
"token" => token
} = session
socket
|> assign_new(:token, fn -> token end)
|> assign_new(:host, fn ->
get_connect_params(socket)["host"] || raise "pass in the host!"
end)
|> setup_context(session, params)
end
defp setup_context(socket, _session, params) do
socket =
socket
|> assign_new(:context, fn ->
{:ok, ctx} =
Common.Sensetra.lookup_context(
socket.assigns.host,
params["organization_id"],
socket.assigns.token
)
ctx
end)
socket
|> assign(CommonWeb.Plug.Application.assigns_from_context(socket.assigns.context))
end
end
I use assign_new
because I also call Common.Sensetra.lookup_context()
inside of a plug. That plug will do things like redirect you to login if there is no current user. Since I look it up in the conn, I use assign_new
so that in the socket part of the GET request it isn’t called twice.
You can mostly ignore the whole "host"
thing I pass in. Our application does subdomain based theming so it’s important for us.