Authentication is the middleware layer that runs on every request, so its cost model matters twice: once per request for verification, and once per session for issuance and refresh. This trace follows one login through JWT issuance, per-request verification, and the refresh flow that keeps the session alive.
1. Login authenticates credentials
The client POSTs credentials to /auth/login. The handler checks them against the credential store — a password hash compare (bcrypt ~100ms, argon2 ~200ms — deliberately expensive), or an OAuth exchange with an IdP. On success, the server must decide what to hand back. The answer is a token pair: a short-lived access token (the key the client presents on every request) and a long-lived refresh token (the key used to mint new access tokens).
2. The access token is issued
The server builds the JWT — three base64url segments joined by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTc1NTY2MzIwMCwiaWF0IjoxNzU1NjYyMzAwfQ.VTjZSk9...signatureHeader (algorithm), payload (subject, role, iat, exp), signature. The server signs with its key: HS256 (HMAC, ~5-20µs) or RS256/ES256 (asymmetric, ~50-200µs). Issuance cost per login: sub-millisecond. The refresh token is a separate secret — a random 256-bit string stored hashed in the DB with a TTL (e.g. 30 days), not a JWT.
3. The client stores and sends the token
The client stores the access token (memory or secure storage) and attaches it to every request: Authorization: Bearer eyJhbGciOi.... The server never stores the access token — it is a self-contained credential. That is the trade: no lookup per request, but no way to revoke before exp.
4. Middleware verifies the signature
On each request, the auth middleware splits the token, base64url-decodes header and payload, and verifies the signature against the public key (RS256) or shared secret (HS256). Verification includes checking the alg header against an allowlist — accepting alg: none or HS256 on an RSA key is a real, documented class of vulnerability. Cost: 10-200µs of CPU, zero network. This runs before the handler sees anything, and a failed verification returns 401 immediately — the request never reaches business logic.
5. Middleware checks expiry and claims
The payload's exp (and nbf) are integer timestamp comparisons — sub-microsecond. Then claims: subject present, role or scope allowed for the route. A route requiring admin checks role here, not in the handler — centralizing authorization in middleware is what makes a permission change a config change instead of a code audit. The token's iat can also bound how old a token is allowed to be for sensitive operations.
6. The access token expires
A typical access token lives 5-15 minutes. At exp, every request fails verification with 401 — by design, not by accident: a stolen token is a thief for 15 minutes, not a month. The client now needs a new one, which is exactly what the refresh flow is for. If the client has no refresh token (a fresh session), the user re-authenticates.
7. The refresh flow rotates the token pair
The client POSTs the refresh token to /auth/refresh (with credentials or a cookie-bound CSRF token). The server looks up the hashed refresh token in the DB:
- Replay check: the token must exist and match the hash. If it does not match anything — or has already been rotated — this is a stolen-token signal. Best practice: revoke the whole session's tokens.
- TTL check:
30 days— beyond that, the session ends and the user logs in again. - Issue: a new access token (fresh 15-min life) and a new refresh token. The old refresh token is rotated out: marked used, replaced. Rotation means each refresh token works exactly once — a stolen refresh token is also a one-shot, and its use reveals the theft.
The cost summary
Per request: one signature verify (10-200µs) + two integer comparisons, no I/O — cheaper than any DB-backed session, at the price of no instant revocation. Per login: one expensive password check (100-200ms, deliberate) + one issuance. Per refresh: one DB lookup + one rotation write + one issuance. The system's security hinges on three details: short exp, signed-with-allowlist-check, and refresh tokens that are one-shot secrets stored only as hashes.