Quick JWT Reference
JSON Web Tokens (JWT) are compact, self-contained tokens used for authentication and information exchange. This guide covers the essential reference information for working with JWTs.
JWT Structure At A Glance
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
│──────────────────────────────────────│──────────────────────────────────────────────────────│──────────────────────────────────────────────────│
Header Payload Signature
Each section is Base64URL encoded and separated by dots.
Standard JWT Claims
| Claim | Name | Type | Description |
|---|---|---|---|
iss |
Issuer | String | Who issued the token |
sub |
Subject | String | Token subject (usually user ID) |
aud |
Audience | String/Array | Who the token is for |
exp |
Expiration | Number | Unix timestamp when it expires |
nbf |
Not Before | Number | Unix timestamp before which it's invalid |
iat |
Issued At | Number | Unix timestamp when issued |
jti |
JWT ID | String | Unique token identifier |
Common Signing Algorithms
| Algorithm | Type | Description |
|---|---|---|
| HS256 | Symmetric | HMAC with SHA-256. Same secret for signing and verification. Simple but requires sharing the secret. |
| HS384 | Symmetric | HMAC with SHA-384. Stronger than HS256. |
| HS512 | Symmetric | HMAC with SHA-512. Strongest HMAC variant. |
| RS256 | Asymmetric | RSA with SHA-256. Private key signs, public key verifies. |
| RS384 | Asymmetric | RSA with SHA-384. |
| RS512 | Asymmetric | RSA with SHA-512. |
| ES256 | Asymmetric | ECDSA with P-256. Smaller keys than RSA. |
| PS256 | Asymmetric | RSA-PSS with SHA-256. More secure than RS256. |
| EdDSA | Asymmetric | Ed25519. Modern, fast, secure. |
How to Verify a JWT
// Node.js - using jsonwebtoken
const jwt = require('jsonwebtoken');
// Verify with symmetric secret
try {
const decoded = jwt.verify(token, 'your-secret-key');
console.log(decoded.sub, decoded.exp);
} catch (err) {
// TokenExpiredError, JsonWebTokenError, NotBeforeError
}
// Verify with public key (RS256)
const publicKey = fs.readFileSync('public.pem');
const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
# Python - using PyJWT
import jwt
decoded = jwt.decode(token, secret, algorithms=["HS256"])
JWT Security Checklist
Always verify the signature on the server before trusting any claims. Check the exp claim and reject expired tokens. Specify allowed algorithms explicitly to prevent algorithm confusion attacks. Never store sensitive data in the payload since it is only Base64 encoded, not encrypted. Use short expiry times (15-60 minutes for access tokens) combined with refresh tokens. Implement token revocation via a blocklist if needed. Use HTTPS to prevent token interception. Store tokens in HttpOnly cookies or memory, not localStorage, to reduce XSS risk.
Decoding Without Verification
Sometimes you need to read claims from a JWT without verifying (for example, to check expiry before making a network call to refresh):
// WARNING: Do NOT use for security decisions
const parts = token.split('.');
const payload = JSON.parse(atob(parts[1]));
console.log(payload.exp); // Unix timestamp
This is safe only for display purposes or pre-verification checks.
JWT vs Session Tokens
Sessions store state on the server (in a database or Redis) and give the client only an opaque ID. JWTs embed state directly in the token, making the server stateless. This makes JWTs excellent for microservices and distributed systems where every service can verify tokens independently using a public key, without making database calls.
The tradeoff is that JWTs are harder to revoke: you cannot invalidate a signed JWT before its expiry without maintaining a server-side blocklist (which partially negates the stateless benefit).
Using This Tool
Paste any JWT to instantly decode and inspect the header, payload, and signature. The tool shows:
- Algorithm and token type from the header
- All claims with human-readable timestamps for numeric dates
- Expiry status (valid, expired, or time remaining)
- Raw Base64URL-decoded content of each section
-> Try the JWT Parser