JWT Authentication Architecture: Access Tokens, Refresh Rotation & XSS/CSRF Defense
Master production JSON Web Token (RFC 7519) security: structure of Header.Payload.Signature, short-lived access tokens, HttpOnly refresh token rotation, and reuse detection.
JSON Web Tokens (JWT, RFC 7519) power stateless authentication across modern microservices, mobile apps, and single-page applications. Yet misconfigured JWT implementations—such as storing long-lived tokens in localStorage or failing to validate signing algorithms—remain a top cause of account takeover vulnerabilities.
You can inspect raw token payloads locally using the Base64 Decoder and test authenticated Bearer header flows in our HTTP API Playground.
1. Inside the Three Base64URL Segments of a JWT
Every signed JWT consists of three dot-separated Base64URL strings: Header.Payload.Signature.
// 1. Header (Algorithm & Token Type)
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-2026-11"
}
// 2. Payload (Registered & Custom Claims)
{
"sub": "usr_948102",
"iss": "https://auth.example.com",
"aud": "https://api.example.com",
"role": "admin",
"iat": 1762070400,
"exp": 1762071300 // 15-minute expiration TTL
}
// 3. Cryptographic Signature
RSASHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
privateKey
)
2. Production Checklist: Access vs. Refresh Token Rotation
- Short-Lived Access Tokens (5 to 15 minutes): Sent in the
Authorization: Bearer <token>header. Verified statelessly by API gateways using the issuer's public JWKS key. - Rotating Refresh Tokens (7 to 30 days): Stored in an
HttpOnly; Secure; SameSite=Strictcookie. Every time a refresh token is exchanged for a new access token, issue a brand-new refresh token and invalidate the old one in Redis/PostgreSQL. - Algorithm Pinning: Explicitly whitelist allowed algorithms (e.g.,
['RS256', 'ES256']) in your verifier to preventalg: "none"and RSA-to-HMAC key-confusion attacks.
Frequently Asked Questions
Can anyone read the data inside a standard JWT payload?
Yes! A standard JWS (JSON Web Signature) is merely Base64URL-encoded, NOT encrypted. Anyone who intercepts the token can decode the header and payload using a Base64 decoder. Never store plaintext passwords, SSNs, or secret API keys inside a JWT payload.
Where should a React SPA store JWT access and refresh tokens?
Store the long-lived Refresh Token in an HttpOnly, Secure, SameSite=Strict cookie so JavaScript XSS payloads cannot read it. Keep the short-lived Access Token (5–15 min TTL) in memory inside your application state.