diagram.mmd — sequence
JWT Authentication Flow sequence diagram

A JSON Web Token (JWT) is a compact, URL-safe token format used to represent claims between two parties. In authentication contexts, JWTs serve as self-contained access tokens that a server can validate without querying a database — making them ideal for stateless, horizontally-scaled APIs.

A JWT consists of three Base64URL-encoded parts separated by dots: a header (algorithm and token type), a payload (claims), and a signature. The header specifies the signing algorithm — typically HS256 (HMAC-SHA256, symmetric) or RS256 (RSA-SHA256, asymmetric). The payload contains standard claims like sub (subject/user ID), exp (expiry timestamp), iat (issued at), and iss (issuer), plus any application-specific claims like roles or permissions.

The flow begins with a login request. The client sends credentials (username + password, or an OAuth2 code) to the authentication server. After verifying the credentials, the server creates a JWT payload, signs it with the secret or private key, and returns the token to the client.

The client stores the JWT — typically in memory or an httpOnly cookie — and attaches it to every subsequent request as an Authorization: Bearer header. When the resource server receives the request, it extracts the token, decodes the header to identify the algorithm, fetches the public key or secret, and verifies the signature. It then checks exp to ensure the token hasn't expired. No database lookup is needed: all claims are self-contained.

The trade-off of statelessness is that JWTs cannot be revoked before expiry without maintaining a denylist. This is why access tokens are kept short-lived (5–60 minutes) and paired with a Refresh Token Rotation strategy. For session-based alternatives that are easier to invalidate, compare Session Based Authentication. Token revocation patterns are covered in Token Revocation Flow.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

JWT (JSON Web Token) authentication is a stateless method where the server issues a signed token containing user claims. The client presents this token on every request, and the server validates the signature locally without querying a database — making it well-suited for horizontally scaled APIs.
The resource server extracts the token from the `Authorization: Bearer` header, decodes the header to identify the signing algorithm, retrieves the appropriate public key or secret, and verifies the signature. It then checks the `exp` claim to confirm the token has not expired, and optionally verifies `iss` (issuer) and `aud` (audience). If all checks pass, the claims in the payload are trusted.
Standard claims include `sub` (subject — the user ID), `exp` (expiry timestamp), `iat` (issued at), `iss` (issuer), and `aud` (audience). Applications commonly add custom claims like `roles`, `permissions`, `email`, or `tenant_id` to carry authorization context directly in the token.
The biggest risk is that JWTs cannot be revoked before expiry without a denylist, so a stolen access token is valid until it expires. Use short expiry windows (5–15 minutes). Never store JWTs in `localStorage` — prefer `httpOnly` cookies to prevent XSS theft. Always validate `alg`, `iss`, `aud`, and `exp`; never accept the `none` algorithm.
Session-based auth stores state on the server: a session record is looked up on every request, making revocation instant but requiring shared server-side storage. JWT auth is stateless: the token carries all claims and is validated locally without a database, enabling simpler horizontal scaling — but revocation requires either a denylist or short expiry times.
mermaid
sequenceDiagram participant Client participant AuthServer as Auth Server participant API as Resource Server Client->>AuthServer: POST /login with credentials AuthServer-->>AuthServer: Verify credentials AuthServer-->>AuthServer: Build payload (sub, exp, iat, roles) AuthServer-->>AuthServer: Sign JWT with private key AuthServer-->>Client: Signed JWT access token Client->>API: GET /api/resource with Authorization: Bearer JWT API-->>API: Decode JWT header and payload API-->>API: Fetch public key (or use shared secret) API-->>API: Verify signature alt Signature valid and not expired API-->>API: Extract claims (sub, roles) API-->>Client: 200 OK with resource data else Token expired API-->>Client: 401 Unauthorized - token expired Client->>AuthServer: POST /token with refresh token AuthServer-->>Client: New access token else Invalid signature API-->>Client: 401 Unauthorized - invalid token end
Copied to clipboard