Strategy for require_authenticated_user and mount_current_user live_sessions and avoiding full page reload?

Created a very basic Liveview application with phx.gen.auth.

scope "/", AppWeb do
  pipe_through [:browser, :require_authenticated_user]

  live_session :require_authenticated_user,
    on_mount: [{AppWeb.UserAuth, :ensure_authenticated}] do
    live "/users/settings", UserSettingsLive, :edit
  end
end

scope "/", AppWeb do
  pipe_through [:browser]

  live_session :current_user,
    on_mount: [{AppWeb.UserAuth, :mount_current_user}] do
    live "/game/:slug", GameLive.Show
end

On the Game liveview page, if the user is logged in I just show if he’s favorited the game or not. But that same page can also be seen by anonymous users.

So far it all works perfectly.

But a nasty side effect of having two different live_session’s is that with navigating from the settings page to the game page, it triggers a full page reload.

What strategies do you recommend to address this situation?

After some noodling I ended up with this approach.

  1. I moved all of my routes to the live_session :current_user to avoid the full page reloads. The site is much snappier now.

  2. In the pages that I know require an authenticated user, I added this:

use MyAppWeb, :live_view

on_mount {MyAppWeb.UserAuth, [:ensure_authenticated, "/super-secret-page"]}

The string parameter is a redirect post-login so that people are sent back to where they were.

  1. Finally in the user_auth.ex file, I pattern matched for this case.
def on_mount([:ensure_authenticated, user_return_to], _params, session, socket) do
  socket = mount_current_user(session, socket)

  if socket.assigns.current_user do
    {:cont, socket}
  else
    socket =
      socket
      |> Phoenix.LiveView.put_flash(:error, "You must log in to access this page.")
      |> Phoenix.LiveView.redirect(to: ~p"/users/log_in?continue=#{user_return_to}")

    {:halt, socket}
  end
end
1 Like