JWT (JSON Web Token) Cheat Sheet

JWT Structure

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NSJ9.signature
└─────── Header β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€ Payload β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€ Signature β”€β”€β”˜

Three Base64URL-encoded parts separated by dots.

{
  "alg": "HS256",
  "typ": "JWT"
}
FieldRequiredValues
algYesHS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, EdDSA, none (reject this!)
typNoUsually β€œJWT”
kidNoKey ID β€” identifies which key to use for verification

Registered Claims (RFC 7519)

ClaimNameTypeExample
subSubjectstring"user-123"
issIssuerstring"https://auth.example.com"
audAudiencestring or array"https://api.example.com"
expExpirationnumber (Unix timestamp)1716239022
iatIssued Atnumber (Unix timestamp)1516239022
nbfNot Beforenumber (Unix timestamp)1516239022
jtiJWT IDstring"abc-123-def"

All claims are optional. Custom claims (e.g., role, email, permissions) can be added freely.

Signing Algorithms

Symmetric (shared secret)

AlgorithmDescriptionKey Size
HS256HMAC + SHA-256256-bit secret
HS384HMAC + SHA-384384-bit secret
HS512HMAC + SHA-512512-bit secret

Same key signs and verifies. Both parties must have the secret.

Asymmetric (public/private key pair)

AlgorithmDescriptionKey Type
RS256RSA + SHA-256RSA 2048+ bit
RS384RSA + SHA-384RSA 2048+ bit
RS512RSA + SHA-512RSA 2048+ bit
ES256ECDSA + P-256EC P-256
ES384ECDSA + P-384EC P-384
ES512ECDSA + P-521EC P-521
PS256RSASSA-PSS + SHA-256RSA 2048+ bit
EdDSAEdwards-curve DSAEd25519

Private key signs, public key verifies. Better for distributed systems.

HS256 vs RS256

HS256RS256
TypeSymmetricAsymmetric
KeyShared secretPublic/private pair
SignSecretPrivate key
VerifySame secretPublic key
SpeedFasterSlower
Best forSingle serverMicroservices, 3rd-party verification

Decode (Without Verification)

JavaScript

const [header, payload] = token.split('.').slice(0, 2)
  .map(p => JSON.parse(atob(p.replace(/-/g, '+').replace(/_/g, '/'))));

Python

import jwt
payload = jwt.decode(token, options={"verify_signature": False})

Command Line

echo "eyJhbGci..." | cut -d. -f2 | base64 -d 2>/dev/null

Verify (With Key)

JavaScript (jsonwebtoken)

const jwt = require('jsonwebtoken');
const decoded = jwt.verify(token, secret, { algorithms: ['HS256'] });

Python (PyJWT)

import jwt
payload = jwt.decode(token, secret_key, algorithms=["HS256"])

Go (golang-jwt)

token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
    return []byte(secretKey), nil
})

Token Lifetime Pattern

Login β†’ Access Token (15 min) + Refresh Token (7-30 days)
       β”‚
       β”œβ”€β”€ API Request β†’ send Access Token in Authorization header
       β”œβ”€β”€ Access Token expires β†’ use Refresh Token to get new Access Token
       └── Refresh Token expires β†’ user must log in again

Security Checklist

  • Always verify signature server-side before trusting claims
  • Reject alg: none β€” explicitly whitelist allowed algorithms
  • Check exp claim β€” reject expired tokens
  • Check iss and aud β€” verify token is from expected issuer for expected audience
  • Use short-lived access tokens β€” 15-60 minutes max
  • Store in httpOnly cookies β€” not localStorage (vulnerable to XSS)
  • Use HTTPS only β€” tokens in transit must be encrypted
  • Never put secrets in payload β€” JWT payload is encoded, not encrypted
  • Rotate signing keys periodically
  • Use RS256 for distributed systems β€” don’t share secrets across services

Common Mistakes

MistakeWhy It’s BadFix
alg: none acceptedAttacker can forge tokens without signatureWhitelist algorithms: { algorithms: ['HS256'] }
Payload treated as secretAnyone can Base64-decode the payloadNever put passwords/keys in JWT
Long expiration (24h+)Stolen token is valid for too longUse 15-60 min access + refresh token
Stored in localStorageXSS can steal the tokenUse httpOnly secure cookies
Secret key too shortBrute-force attack possibleUse 256+ bit random secret
No exp validationExpired tokens acceptedAlways check expiration server-side

HTTP Authorization Header

Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NSJ9.signature
jwt authentication security api reference

Related Tools

More Cheat Sheets