pentacent / phoenix_live_session

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

Fails to load current session on redirect #1

Open bradrf opened 3 years ago

bradrf commented 3 years ago

I'm very new to using Phoenix LiveView, so take this with a large grain of salt. I have Live Sessions working (super easy—thank you!), but they appear to not provide the current session when using push_redirect. The session available in the destination LiveView appears to be the default values until the page is refreshed to force a full request made which then loads the session values (including the "user_id" added from the previous page). Is there some other mechanism I should be utilizing when navigating across LiveViews to ensure the session is available?

Example of session from redirect:

%{
    :__opts__ => [
      clean_interval: 60000,
      lifetime: 172800000,
      table: :phoenix_live_sessions,
      pub_sub: MyApp.PubSub,
      signing_salt: "XXX"
    ],
    :__sid__ => "XXX",
    "_csrf_token" => "XXX"
  }

And then as it's populated following the page reload:

%{
    :__opts__ => [
      clean_interval: 60000,
      lifetime: 172800000,
      table: :phoenix_live_sessions,
      pub_sub: MyApp.PubSub,
      signing_salt: "XXX"
    ],
    :__sid__ => "XXX",
    "_csrf_token" => "XXX",
    "user_id" => 87632            // <--- the ID from the stored session from previous page
  }
bradrf commented 3 years ago

Minor update: seems to work fine with a "normal" redirect.

wmnnd commented 3 years ago

Could you share the mount callback of your second LiveView?

bradrf commented 3 years ago

Definitely!

  def mount(%{"room_id" => room_id} = _params, session, socket) do
    room = Rooms.get_room!(room_id)
    user = Users.get_user!(session["user_id"])

    socket = assign(socket, user: user, room: room)

    if connected?(socket) do
      case RoomMaster.join_room(room.name, user.name, self()) do
        {:ok, ot_room} ->
          {:ok, assign(socket, ot_room: ot_room)}

        {:error, reason} ->
          {:ok, socket |> put_flash(:error, reason) |> redirect(to: "/")}
      end
    else
      {:ok, socket}
    end
  end
Hanspagh commented 3 years ago

I am having the same problem. Can I help in any way

wmnnd commented 3 years ago

It looks like you’re not calling the maybe_subscribe/2 function in your mount/3 callback.

eduardozacour commented 2 years ago

I am also having this issue. When I do a live_redirect to another live view, the session map in the mount callback for the view is not updated yet. Only when I do a refresh of the page, the new session is provided to the mount callback in the view. Let me know if there is anything I can do to help, and great job on the library by the way.

jon-mcclung-fortyau commented 2 years ago

I'm having the same issue as well, even when calling maybe_subscribe/2 the session never persists after a push_redirect. Isn't that the whole point? If I'm not changing up live views I can just use socket.assigns...

tjhayasaka commented 2 years ago

This is my workaround:

def mount(_params, session, socket) do
  socket = PhoenixLiveSession.maybe_subscribe(socket, session)
  session = get_live_session(socket, session)

  # do something with the session...
end

def get_live_session(socket, session) do
  sid = get_in(socket.private, [:live_session, :id])
  opts = get_in(socket.private, [:live_session, :opts])
  if sid == nil or opts == nil do
    session
  else
    {_, session} = PhoenixLiveSession.get(nil, sid, opts)
    session
  end
end
tnohtition commented 5 months ago

I've faced the same issue. So the solution is invoking redirect/2 right after the PhoenixLiveSession.put_session/3. Guessing the session doesn't load on the push_navigate/3. It's required a full page load