LiveView’s live-cycle starts with plain html rendering, then js code responsible for web socket connection gets executed and upgrades our connection to interactive LiveView session.
If we have authentication plug, which is responsible to check for valid session and redirect to login if something fails, then we wouldn’t reach the LiveView stage.
scope "/", AppWeb do
live "/", PageLive, :index
live "/admin", AdminLive.Show, :show
In general, web socket connections are completely separate scope from plug pipelines.
But if we use
live_redirect on another LiveView page to generate link to the AdminLive, in theory, we should completely escape all plug verifications because we already have upgraded web socket connection, but it seems that my plug authentication still somehow checks the connection and redirects me back to the login page.
Thanks for asking this, I too was surprised by this behavior. (It shuts down the web socket connection and starts a new one.)
I think the meaning of this sentence from the docs is the crux, and isn’t completely clear:
The current LiveView will be shut down and a new one will be mounted in its place, without reloading the whole page.
In what sense is a new LiveView mounted? In what sense is the whole page not reloaded?
It seems that we continue using current web socket connection because there’re no new
[info] CONNECTED TO Phoenix.LiveView.Socket messages in logs.
Even if we trigger new connection, it still should not interact with plug pipelines.
Ok, I kind of get it after exploring sources of Phoenix LiveView.
It seems that
phoenix_live_view.js captures click event and sends XHR to target url (
/admin). It executes all plugs as any regular request.
If all is OK, it returns a div with required credentials to request LiveView render via web socket. You can’t just ask it yourself because you need to get signed token for your session which permits you to ask particular LiveView render in yours session.
XHR response looks like
<div data-phx-session="%long-encoded-signed-session-token%" data-phx-view="AdminLive.Show" id="phx-%liveview-id%"></div>
If you parse all the attributes you could ask web socket to render your LiveView by sending a message to LiveView channel.