Understanding JSON Web Tokens
JWTs are everywhere in modern web development, but they are often misunderstood. Let us break them down.
Structure
A JWT consists of three base64-encoded parts separated by dots:
header.payload.signature
Header specifies the algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
Payload contains claims:
{
"sub": "1234567890",
"name": "John",
"iat": 1516239022,
"exp": 1516242622
}
Signature ensures integrity:
HMACSHA256(base64(header) + "." + base64(payload), secret)
Common Mistakes
1. Storing Sensitive Data in Payload
JWTs are signed, not encrypted. Anyone can decode the payload:
echo "eyJzdWIiOiIxMjM0NTY3ODkwIn0" | base64 -d
# {"sub":"1234567890"}
Never put passwords, credit card numbers, or PII in JWT payloads.
2. Not Validating Expiration
Always check the exp claim. A JWT without expiration is a security risk.
3. Using Weak Secrets
For HMAC-based JWTs, use at least 256 bits of entropy:
openssl rand -base64 32
When to Use JWTs
Good for:
- Stateless authentication between microservices
- Short-lived access tokens (15-30 minutes)
- Single sign-on across domains
Not ideal for:
- Session management (use server-side sessions instead)
- Long-lived tokens (use refresh tokens)
- Storing large amounts of data
The key takeaway: JWTs are a tool, not a solution. Use them where statelessness is genuinely needed.