Learn
Cheatsheet
JWT
Structure, claims, algorithms, and security rules at a glance.
Token Structure
| header.payload.signature | Three Base64Url parts separated by dots |
| { "alg": "HS256", "typ": "JWT" } | Header — algorithm and token type |
| { "sub": "123", "name": "Alice", "exp": 1700000000 } | Payload — JSON claims (readable by anyone — do not store secrets here) |
| HMACSHA256(base64url(header) + "." + base64url(payload), secret) | Signature — proves the token was not tampered with |
Standard Claims
| sub | Subject — who the token is about (usually a user ID) |
| iss | Issuer — which service created the token |
| aud | Audience — which service should accept the token |
| exp | Expiration — Unix timestamp; token is invalid at or after this time |
| iat | Issued at — Unix timestamp when the token was created |
| nbf | Not before — token is not valid before this timestamp |
| jti | JWT ID — unique identifier, used to prevent replay attacks |
Algorithms
| HS256 | HMAC + SHA-256 — symmetric, single shared secret |
| HS384 / HS512 | HMAC variants with longer hash output |
| RS256 | RSA + SHA-256 — asymmetric, sign with private key, verify with public |
| ES256 | ECDSA + P-256 — asymmetric, smaller keys than RSA |
Security Rules
| Always verify the signature server-side | Never trust claims from an unverified token |
| Reject alg: none | Unsigned tokens are not valid — always enforce the expected algorithm |
| Check exp on every request | Expired tokens must be rejected even if the signature is valid |
| Store tokens in httpOnly cookies | Protects against XSS; avoid localStorage for sensitive tokens |
| Short expiry + refresh token pattern | 15-minute access token paired with a long-lived refresh token is best practice |