JWTs are everywhere in modern authentication flows, yet they're frequently misused. Here's a comprehensive but concise breakdown.
Structure: three Base64URL-encoded parts
A JWT looks like xxxxx.yyyyy.zzzzz:
- Header — algorithm and token type:
{"alg":"HS256","typ":"JWT"} - Payload — claims (user ID, roles, expiry):
{"sub":"123","exp":1718000000} - Signature — HMAC or RSA signature over header + payload, using your secret
What the signature guarantees
The signature proves the token hasn't been tampered with. It does NOT encrypt the payload — anyone can decode and read the header and payload. Never store sensitive data (passwords, PII) in a JWT payload.
Critical security mistakes
- Accepting
alg: none— always explicitly specify the expected algorithm when verifying. - No expiry (
exp) — tokens without expiry are valid forever if stolen. - Storing in localStorage — vulnerable to XSS. Prefer httpOnly cookies.
- Weak secrets — HMAC secrets should be at least 256 bits of randomness.
When to use JWT
JWTs shine for stateless, cross-service authentication. They're overkill for simple session management where a server-side session store works fine.
Inspect any JWT instantly with ByteForge's JWT Decoder — see the header, payload, and signature breakdown without sending the token to a server.