The Runtime Theory
ApplicationDSAarchitecture

Auth Token Trace: JWT Issue, Middleware Verification, and Refresh Flow

A step-by-step walk from login to JWT issuance, middleware signature and expiry verification, and the refresh-token rotation flow.

The Runtime Theory Team3 min read07 steps

trace spine

  1. 01 Login authenticates credentials
  2. 02 Access token is issued
  3. 03 Client stores and sends the token
  4. 04 Middleware verifies signature
  5. 05 Middleware checks expiry and claims
  6. 06 Access token expires
  7. 07 Refresh flow rotates the token pair
On this page

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:

text
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTc1NTY2MzIwMCwiaWF0IjoxNzU1NjYyMzAwfQ.VTjZSk9...signature

Header (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:

  1. 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.
  2. TTL check: 30 days — beyond that, the session ends and the user logs in again.
  3. 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.