Authentication

Auth is token based. A bearer token lives in storage, rides along on every request, and the entire logged-in state is derived from whether a valid one resolves a user. There are no sessions and no cookies, which keeps the two apps and the API cleanly decoupled.

The request side

An http request interceptor attaches the stored token as a Bearer header on every outgoing call, so individual requests never deal with auth themselves. A response interceptor watches for a 401 and, when it sees one, flushes auth state and redirects to login. An expired or rejected token bounces the user out from anywhere in the app without each caller having to handle it.

The boot check

On startup the auth composable runs a readiness check. If there is a token it refreshes it and fetches the user, and if either step fails it flushes and treats the user as logged out. This is what turns a stored token into a live session. It runs in the router's ready gate, so it is settled before any route guard evaluates, and after it resolves once it is a no-op for the rest of the session.

Route protection

Access control hangs off route meta. A route, or any record it nests under, declares an auth block, and the guard merges those across all matched records before deciding.

meta: {
  auth: {
    roles: true,
    redirect: { name: 'auth-login' },
  },
}

roles drives three cases. false is a guest-only route and redirects when the user is logged in, the login and register screens use this. true requires any authenticated user and redirects when logged out. An array requires the user's role to be in the list and redirects otherwise. Every block carries its own redirect, and it needs one. A protected route with no redirect just falls through and gets caught by the 401 handling instead, which is a worse experience.

Sliding sessions

The token refreshes on boot rather than expiring on a fixed wall clock. Each call to the refresh endpoint rotates the token and extends the window, so an active user stays logged in indefinitely and only a real stretch of not opening the app lets the token lapse. How long that window is lives entirely on the API side. The front end just asks for a fresh token and stores whatever comes back.

See also

Login and Token Lifecycle on the API side for how tokens are issued, rotated, and expired. Settings for the ready gate this shares with settings loading.

© Websanova 2026 About Privacy