Who is signed in, on a connection and in a LiveView, from one place.
pipeline :browser do
plug :fetch_session
plug Ithibati.Web.Gate, :current_account
end
live_session :admin, on_mount: [{Ithibati.Web.Gate, {:require_account, to: ~p"/sign-in"}}] do
live "/admin", AdminLive
endThe gate has two modes and no others. :current_account assigns whoever the session names, or
nil, and always continues. :require_account refuses when there is nobody.
An unrecognised mode raises rather than being ignored. The plug raises from init/1, which
Phoenix runs at compile time under init_mode: :compile and at the first request otherwise;
the on_mount raises at the mount either way. A gate that listed its modes and let anything
else through would turn a typo into a page that refuses nobody, and nothing would report
it.
The gate covers authentication and stops there. What an account may do is the application's, and Ithibati has no opinion about it.
Summary
Functions
The topic the sockets of one session answer on.
Signs an account in by storing a session token under Ithibati's session key.
Signs out and revokes the token rather than merely forgetting it.
The same two modes, for LiveView.
The session key Ithibati stores its token under.
Functions
The topic the sockets of one session answer on.
Ithibati derives the topic from the token's digest. A topic reaches logs, telemetry and
everything subscribed to the pubsub server, and phx.gen.auth puts the live token itself in
there. The topic is per token rather than per account, so signing out in one browser leaves the
same person's other devices alone.
This function is public for an application that ends a session somewhere other than
log_out/1 and holds the raw token while doing it. It cannot serve "sign out my other
devices": that starts from what the database has, which is digests.
Signs an account in by storing a session token under Ithibati's session key.
Ithibati offers this rather than imposing it. An application decides in Ithibati.Web.Handler
what a verified assertion is worth, and one that issues a bearer token for an extension instead
simply never calls this. The gate then finds nothing, which is the right answer. But a gate
that read a key nothing here ever wrote would leave every application guessing the convention.
log_in/2 renews the session first, because a fixed session id handed to someone before they
sign in is a session an attacker already holds afterwards. Renewing clears the CSRF token along
with everything else, so a sign-in has to end in a full page load. The hook does that when
a handler answers with %{redirect: …}. A page that stays put after signing in holds a token
the new session has never heard of, and its next form post is refused.
Signs out and revokes the token rather than merely forgetting it.
A session dropped on the client alone leaves a token that still resolves. That is the sign-out counterpart of a replayed assertion, and it fails just as quietly.
The same two modes, for LiveView.
:require_account takes :to here and has no default. A LiveView that halts with nowhere to
send a person is a dead end, and the path belongs to the application.
The session key Ithibati stores its token under.