The Concert Wristband Analogy
At a music festival:
- You show ID at the gate, get a wristband
- Wristband proves you paid and your access level (VIP, general)
- Security just checks the wristband - no need to verify ID again
- Wristband has anti-tampering features (can't fake it)
JWT is a digital wristband. If it's signed and verified correctly, it’s designed to be tamper-evident.
What Is a JWT?
JWT = JSON Web Token
A compact, URL-friendly token containing:
- WHO you are (claims)
- WHAT you can do (permissions)
- WHEN it expires
- SIGNATURE proving it's authentic
JWT Structure
xxxxx.yyyyy.zzzzz
Header.Payload.Signature
Three parts, separated by dots.
The Three Parts
1. Header
{
"alg": "HS256", ← Algorithm used to sign
"typ": "JWT" ← Token type
}
Base64URL encoded → eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
2. Payload (Claims)
{
"sub": "user123", ← Subject (user ID)
"name": "Alice", ← User data
"role": "admin", ← Permissions
"iat": 1704067200, ← Issued at (timestamp)
"exp": 1704153600 ← Expires at (timestamp)
}
Base64URL encoded → eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIn0
Note: JWTs often include timestamps like `iat`/`exp`, but the exact claims you use depend on your needs and your identity provider.
3. Signature
HMAC-SHA256(
base64(header) + "." + base64(payload),
secret_key
)
Encoded → SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
This proves the token wasn't tampered with!
Complete JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
How JWT Works
Generation Flow
1. User logs in with username/password
2. Server verifies credentials
3. Server creates JWT:
- Puts user info in payload
- Signs with secret key
- Returns JWT to client
4. Client stores JWT
(Cookie, memory, etc.)
Note: Storing tokens in web-accessible browser storage can increase risk if your site has an XSS bug. Using `httpOnly` cookies can reduce token exfiltration via JavaScript, but you must design for CSRF defenses (for example, SameSite and anti-CSRF tokens).
Verification Flow
1. Client sends request with JWT:
Authorization: eyJhbGciOiJS...
2. Server receives JWT
3. Server verifies:
- Signature is valid (not tampered)
- Token not expired
- Claims are appropriate
4. Server grants access
In the simplest setup, the server can verify the signature without a session database lookup. In practice, many systems still do lookups for revocation, user status changes, or fine-grained permissions.
Why JWT?
Stateless Authentication
Traditional session:
Server stores session → Database lookup every request
JWT:
Token contains all info → No database lookup
Server just verifies signature
Result: More scalable!
Benefits
✓ Self-contained (all info inside)
✓ Stateless (no server-side storage)
✓ Scalable (any server can verify)
✓ Works well for APIs and distributed systems
✓ Mobile-friendly
JWT Claims
Standard Claims
| Claim | Name | Description |
|---|---|---|
| iss | Issuer | Who created the token |
| sub | Subject | Who the token is about |
| aud | Audience | Who the token is for |
| exp | Expiration | When token expires |
| iat | Issued At | When token was created |
| nbf | Not Before | Token not valid before |
| jti | JWT ID | Unique token identifier |
Custom Claims
{
"sub": "user123",
"email": "alice@example.com",
"role": "admin",
"permissions": ["read", "write", "delete"],
"organization_id": "org456"
}
Add whatever your app needs!
Signing Algorithms
Symmetric (HMAC)
HS256, HS384, HS512
Same key to sign and verify.
Fast and simple.
Both parties need the secret key.
Asymmetric (RSA, ECDSA)
RS256, ES256
Private key to sign.
Public key to verify.
Server signs with private key.
Anyone can verify with public key.
When to Use Which
Symmetric (HMAC):
Simple apps, same server signs and verifies
Asymmetric (RSA/ECDSA):
Microservices (one service signs, many verify)
Third-party verification needed
Security Considerations
1. Verify the Signature
Don't just decode and trust.
Verify the signature with your secret/public key before trusting any claims.
2. Check Expiration
Expired token? Reject!
Don't let old tokens work forever.
3. Use HTTPS
If you send tokens over unencrypted HTTP, someone on the network path may be able to capture them.
Send JWTs over HTTPS (or another encrypted transport).
4. Keep Secrets Secret
If HMAC secret is leaked:
Anyone can forge valid tokens!
Store secrets securely (env vars, vault).
5. Don't Store Sensitive Data
Most JWTs you see in auth systems are signed (JWS), not encrypted.
That means the payload is readable to anyone who has the token.
Don't put:
- Passwords
- Credit card numbers
- Sensitive personal data
If you need confidentiality, look into encrypted JWTs (JWE) or keep sensitive data server-side.
Token Lifetime Strategies
Short-Lived Access Tokens
Lifetime: Often short-lived (varies by system)
Purpose: API access
If stolen: Limited damage window
Refresh Tokens
Lifetime: Often longer-lived than access tokens (varies by system)
Purpose: Get new access tokens
Stored securely (httpOnly cookie)
Flow
1. Login → Access token + (optionally) refresh token
2. Use access token for API calls
3. Access token expires
4. Use refresh token to get new access token
5. Continue using API
6. Refresh token expires → Log in again
Common Mistakes
1. Using JWT for Sessions
JWTs can't be invalidated easily!
User logs out but token still valid until expiry.
For immediate logout needs, use:
- Short expiry + refresh tokens
- Token blacklist (defeats stateless benefit)
2. "Storing" Secrets in JWT
Payload is Base64 encoded, NOT encrypted!
Anyone can decode and see contents.
Avoid putting sensitive data in JWTs.
3. Allowing "alg: none"
Misconfiguration can lead to accepting unsigned tokens.
Validate the algorithm and reject unexpected values (including "none").
Also avoid algorithm confusion (for example, treating an asymmetric key as an HMAC secret) by using a JWT library with defensive defaults.
4. Not Validating Issuer/Audience
Token from wrong source should be rejected.
Verify `iss` and `aud` when they matter for your system.
FAQ
Q: JWT vs Session cookies?
JWTs: stateless, scalable, cross-domain Sessions: easier to invalidate, server-controlled
Q: Can I invalidate a JWT?
Not directly (stateless). Use short expiry, blacklists, or token versioning.
Q: Where should I store JWTs?
httpOnly cookies: often a good default Web-accessible browser storage: convenient but vulnerable to XSS Memory: can reduce persistence, but lost on refresh
Q: How long should JWTs live?
It depends on your threat model and UX needs. Many systems keep access tokens short-lived and use refresh tokens (or re-auth) to extend sessions.
Summary
JWT is a self-contained token format for stateless authentication and authorization.
Key Takeaways:
- Three parts: Header.Payload.Signature
- Self-contained: all info inside the token
- Stateless: no server-side storage needed
- Signature proves authenticity
- Payload is readable, NOT secret
- Use short expiry + refresh tokens
- Verify the signature, expiry, and any claims you rely on (like
iss/aud) - Remember: payload is readable unless you use encryption (JWE)
JWTs power modern APIs and single sign-on!
Note: JWT is a token format. Whether it's a good fit depends on your system's needs (revocation, session control, and risk level).
Related Concepts
Leave a Comment
Comments (0)
Be the first to comment on this concept.
Comments are approved automatically.