Phoenix 1.6.6
Liveview 0.17.6
I’m running into a weird problem after I upgraded to Phoenix 1.6. I have a LiveView route that is behind the Authentication wall. But the LiveView mount3 is being called BEFORE the authentication is invoked. This is raising an error because I use the mount to assign my user to the socket. Code below.
QUESTION: Why is mount being called before the user is forced to login? Shouldn’t phx.gen.auth force the user to first log in if the route is sitting behind a pipe_through [:browser, ::require_authenticated_user]?
CODE:
User clicks button which invokes a handle_event that redirects user:
def handle_event("manage_resources", _params, socket) do
{:noreply, push_redirect(socket, to: Routes.resourceform_manage_resources_path(socket, :index), replace: true)}
end
Route is sitting behind the authentication wall:
scope "/", MyAppWeb do
pipe_through [:browser, :require_authenticated_user]
…
live "/manage-resources", ResourceformLive.ManageResources, :index
…
end
Run Time error raised:
RESOURCEFORM.modify_resources.mount (**NOTE: this is log output telling me that mount has been called**)
[error] GenServer #PID<0.11481.0> terminating
** (UndefinedFunctionError) function nil.id/0 is undefined
nil.id()
(my_app 0.1.0) lib/my_app_web/live/resourceform_live/manage_resources.ex:23: MyAppWeb.ResourceformLive.ManageResources.mount/3
(phoenix_live_view 0.17.6) lib/phoenix_live_view/utils.ex:301: anonymous fn/6 in Phoenix.LiveView.Utils.maybe_call_live_view_mount!/5
(telemetry 0.4.2) /Users/annad/files/Projects/MyAppLinks/App/my_app_links/deps/telemetry/src/telemetry.erl:262: :telemetry.span/3
(phoenix_live_view 0.17.6) lib/phoenix_live_view/channel.ex:949: Phoenix.LiveView.Channel.verified_mount/8
(phoenix_live_view 0.17.6) lib/phoenix_live_view/channel.ex:58: Phoenix.LiveView.Channel.handle_info/2
(stdlib 3.17) gen_server.erl:695: :gen_server.try_dispatch/4
(stdlib 3.17) gen_server.erl:771: :gen_server.handle_msg/6
(stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
[info] GET /manage-resources
[debug] Processing with Phoenix.LiveView.Plug.index/2
Parameters: %{}
Pipelines: [:browser, :require_authenticated_user]
[info] Sent 302 in 1ms
[debug] Phoenix.Router halted in :require_authenticated_user/2
[info] GET /users/log_in
[debug] Processing with MyAppWeb.UserSessionController.new/2
Parameters: %{}
Pipelines: [:browser, :redirect_if_user_is_authenticated]
As you can see above, mount is called and then the router pipelines it to [:browser, :require_authenticated_user]. The problem is that I use mount3 to set the user and grab it’s ID. That is why I’m getting that run time error in the first mount:
@impl true
def mount(_params, session, socket) do
IO.puts "RESOURCEFORM.modify_resources.mount"
# Assign user to socket if not already assigned
socket = assign_current_user(socket, session)
# Get User (authenticated user)
user = socket.assigns.current_user
socket =
socket
|> assign(:user_creator_id, user.id )
|> assign(:resource_forms, list_managed_resourceforms(user.id))
|> assign(:return_to,
Routes.resourceform_manage_resources_path(socket, :index))
{:ok, socket}
end
How do I force login BEFORE the mount?