JSON Web Tokens provide an elegant standard for stateless API authentication, but small implementation mistakes can expose your entire backend to token forgery, session hijacking, or algorithm confusion exploits.
Whether you are building your first authentication service or auditing an enterprise API gateway, here are the 10 essential production rules every software engineer must implement when using JWTs.
Rule 1: Always Enforce an Explicit Algorithm Whitelist
Never let your verification library accept whatever algorithm is specified in the incoming token's header. Attackers can modify the alg header from RS256 to none (signature stripping) or from RS256 to HS256 (key confusion).
🛡️ The 4 Pillars of Production JWT Security
Best Practices// In Node.js jsonwebtoken
jwt.verify(token, publicKey, {
algorithms: ["RS256"] // Strictly allow ONLY RS256!
});
Rule 2: Keep Access Token Expiration Extremely Short
Because stateless JWTs cannot be trivially revoked on demand, an intercepted token gives attackers unmitigated access until it reaches its exp timestamp. Set access token expiration to 5 to 15 minutes, and pair it with a refresh token workflow for continuous user sessions.
Rule 3: Always Validate Standard Registered Claims
Do not just check the cryptographic signature; validate standard claims:
- Issuer (
iss): Does this token originate from your identity provider? - Audience (
aud): Was this token issued specifically for this API service? - Expiration (
exp) and Not Before (nbf): Is the token current? Account for a small clock drift (e.g., 60 seconds tolerance). - Subject (
sub): Does the user or client ID exist and remain active?
Rule 4: Store Tokens in HttpOnly, Secure, SameSite Cookies
In browser environments, avoid localStorage for storing authentication tokens. Any Cross-Site Scripting (XSS) vulnerability anywhere in your web app allows injected JavaScript to steal tokens from localStorage.
Instead, transmit tokens in an HttpOnly; Secure; SameSite=Lax cookie. Browsers prevent JavaScript from accessing HttpOnly cookies, blocking XSS exfiltration while protecting against CSRF attacks.
Rule 5: Keep Payloads Minimal & Never Store Sensitive Data
A JWT signature guarantees integrity, not confidentiality. Anyone who intercepts a JWT can decode the Base64URL payload and read every single claim in plain text.
🚨 Never Store Secrets in JWT Claims
Never include passwords, API keys, social security numbers, credit card tokens, or sensitive personal data in a JWT payload. If you require encrypted payloads, use JSON Web Encryption (JWE - RFC 7516) instead.
Rule 6: Use Cryptographically Strong Keys & Secrets
If using HMAC (HS256), your shared secret must have at least 256 bits of cryptographic entropy (at least 32 random bytes generated via a CSPRNG). Weak passwords like secret123 or mycompany-jwt-key can be cracked offline in seconds using GPU-accelerated tools like Hashcat.
openssl rand -base64 32
For RSA algorithms (RS256), use a minimum key length of 2048 bits (or 4096 bits for high-security environments).
Rule 7: Have a Clear Revocation Architecture
Design a revocation strategy before going to production:
- Single-Use Refresh Token Rotation (RTR): Invalidate refresh tokens after every use and revoke token families upon reuse detection.
- Token Epoch / Version: Store a
token_versioninteger on the user record and in the JWT payload. Incrementing the database column instantly invalidates all previously issued tokens for that user. - Redis Revocation List: Cache revoked
jticlaims with an expiration time matching the token's remaining lifespan.
Rule 8: Protect Against CSRF When Using Cookies
If storing JWTs in cookies, defend against Cross-Site Request Forgery:
- Use
SameSite=LaxorSameSite=Strictcookie attributes. - Require a custom header on mutating requests (e.g.
X-Requested-With: XMLHttpRequest) or standard anti-CSRF tokens. Cross-origin form posts cannot attach custom headers without CORS preflight approval.
Rule 9: Enforce TLS / HTTPS Exclusively
Bearer tokens sent over unencrypted HTTP can be intercepted by anyone on the network path (Wi-Fi sniffers, ISP proxies, malicious routers). Enforce HTTPS with HTTP Strict Transport Security (HSTS) across all environments.
Rule 10: Use Established, Audited JOSE Libraries
Never write your own cryptography or token verification logic from scratch. Use battle-tested, actively maintained libraries:
- Node.js:
jose(panva/jose) orjsonwebtoken - Python:
PyJWTorauthlib - Go:
golang-jwt/jwt - Java:
nimbus-jose-jwtorjjwt