Authentication uses Sanctum personal access tokens. No sessions, no cookies.
POST /auth/login validates credentials and returns a token. The client stores it and sends it as a Bearer header on subsequent requests. That's the entire auth flow on the API side.
POST /auth/logout deletes the current token, POST /auth/token/refresh deletes the current token and issues a new one.
Token lifetime is controlled by SANCTUM_TOKEN_EXPIRATION in your .env, defaulting to 10080 minutes (7 days). Sanctum checks this automatically on every authenticated request, so expired tokens just stop working with no extra logic needed.
The starter has no remember me support out of the box. If you need it, the approach is straightforward.
Accept a remember_me flag on the login request and pass an explicit expiration when creating the token:
$expiresAt = $request->remember_me
? now()->addDays(30)
: now()->addHours(2);
$token = $user->createToken('auth', [], $expiresAt);
When expires_at is set on a token, it takes precedence over the global sanctum.expiration config.
That's it for the API. Everything else is client-side: persisting the token, rendering the checkbox, and adjusting refresh behavior based on what the user chose.
The /auth/token/refresh endpoint rotates the current token by deleting it and issuing a new one. This is useful for keeping long-lived sessions alive without re-authenticating.
How the client uses this depends on the token lifetime strategy:
/auth/token/refresh periodically (on app boot, or on a timer) to keep the session alive before the token expires. If the token has already expired, the refresh will 401 and the client redirects to login.The refresh endpoint itself doesn't know or care about remember me. It just issues a new token with the default config expiration. If you're using explicit expires_at for remember me tokens, you'd want the refresh endpoint to carry the same expiration forward, otherwise a refreshed "remember me" token would fall back to the default lifetime.
Expired tokens stay in the database until pruned. The scheduler runs sanctum:prune-expired --hours=1 daily.