pentacent / phoenix_live_session

Live sessions for Phoenix LiveView and Phoenix Controllers
Apache License 2.0
80 stars 19 forks source link

PhoenixLiveSession.put_session not working as expected #10

Open tmthn opened 2 years ago

tmthn commented 2 years ago

I try to update some data within the session when a certain constellation has occurred. As soon as I use the function PhoenixLiveSession.put_session I get the following error:

Request: GET /dashboard
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Keyword.fetch!/2
        (elixir 1.12.3) lib/keyword.ex:417: Keyword.fetch!(nil, :table)
        (phoenix_live_session 0.1.3) lib/phoenix_live_session.ex:159: PhoenixLiveSession.put_in/4
        (phoenix_live_session 0.1.3) lib/phoenix_live_session.ex:261: PhoenixLiveSession.put_session/3

My mount looks like this:

@impl true
  def mount(params, %{"locale" => locale} = session, socket) do
    Gettext.put_locale(ExampleApp.Gettext, locale)

    socket =
      socket
      |> PhoenixLiveSession.maybe_subscribe(session)
      |> MountHelpers.assign_defaults(params, session, {@privileges, :read})
      |> assign_breadcrumbs()
      |> MountHelpers.assign_page_title()

    {:ok, socket, temporary_assigns: [
        user_groups: []
      ]
    }
  end

And i am using the handle info callback as described:

  @impl true
  def handle_info({:live_session_updated, session}, socket) do
    {:noreply, MountHelpers.put_session_assigns(socket, session)}
  end

My put session assigns function looks like this:

def put_session_assigns(socket, session) do
    initial_tokens =
      Map.take(session, ["__idx_token", "__idx_refresh_token", "__idx_id_token"])

    tokens =
      IdxClient.ensure_authenticated(:admin, initial_tokens)

    socket
    |> PhoenixLiveSession.put_session("__idx_token", tokens["__idx_token"])
    |> PhoenixLiveSession.put_session("__idx_refresh_token", tokens["__idx_refresh_token"])
    |> PhoenixLiveSession.put_session("__idx_id_token", tokens["__idx_id_token"])
    |> assign(:tokens, tokens)
 end

Am i doing something wrong?

tmthn commented 2 years ago

Issue is fixed. We used a different approach for updating the session based on your package. Closing this now.

tuomohopia commented 2 years ago

@tmthn how did you manage to sort this out in your project?

tuomohopia commented 2 years ago

As far as I can tell, this occurs because Phoenix.LiveView.connected?/1 returns false when invoked inside mount/3 callback in my project: https://github.com/pentacent/phoenix_live_session/blob/56c0719e7d97a313d8fe859e3dd80af3ba4154f1/lib/phoenix_live_session.ex#L229.

This results in the library not putting in the :live_session key to socket.private, and that's what's missing when we call put_session/3.

tmthn commented 2 years ago

We implemented our own custom session store because i could not dig deeper into this problem due to deadlines with this project. We use similar to the librarys approach an ETS table to store the user tokens and sweep them as they expire. Unfortunately we do not use the PubSub solution used here. To ensure access on both levels (http request and socket connection) we run the ensure access function in both calls. In our custom solution we encountered a similar problem as described here beacuse of the double evaluation of the mount callback. I don't really understand what is causing this problem.

jacksondc commented 3 months ago

Same issue.

jacksondc commented 3 months ago

Oops, seems like my issue was not calling maybe_subscribe.