How web apps keep you logged in: sessions, JWTs & refresh tokens
How do web apps keep you logged in, and how do they log you out? This quiz compares server-side sessions with stateless JWTs, then covers what follows from that choice: where to store tokens (httpOnly cookie or localStorage, and the XSS/CSRF tradeoff), refresh-token rotation, revocation and "log out everywhere" (the hard part of stateless auth), short-lived access tokens, and keeping multiple devices and tabs in sync. It also touches on OAuth 2.0, PKCE, and OpenID Connect. Based on RFC 7519 (JWT), RFC 6749 (OAuth 2.0), RFC 7636 (PKCE), RFC 9700 (OAuth Security BCP), and OpenID Connect Core.
Questions
- Not answered. What's the main tradeoff between a stateless JWT and a server-side session?
- Not answered. A JWT is three base64url segments joined by dots:
header.payload.____. What's the third segment called? - Not answered. Which statements about storing an auth token in the browser are true?
- Not answered. You authenticate with a session cookie. What most directly prevents CSRF?
- Not answered. With refresh-token rotation, a client sends a refresh token that was already used and replaced. What should the server do?
- Not answered. Why are access tokens short-lived (minutes) while refresh tokens last for days?
- Not answered. You use stateless JWT access tokens and need "log out everywhere" to work quickly. Which approaches do that?
- Not answered. What does OpenID Connect (OIDC) add to OAuth 2.0?
- Not answered. Why do public clients (SPAs, mobile apps) use the Authorization Code flow with PKCE instead of the old Implicit flow?
- Not answered. Your servers validate JWTs and sometimes reject freshly issued tokens as "not yet valid" or "expired", depending on which server handles the request. What's the likely cause and fix?
- Not answered. Your SPA is open in three tabs. One tab refreshes the access token, which rotates the refresh token. How should the other tabs avoid using a stale token and avoid all refreshing at once?
- Not answered. Which registered JWT claim uniquely identifies a single token, making it the natural key for a revocation denylist?