JWT Decoder
Decode and inspect JSON Web Tokens. View header, payload, claims, and expiration status.
// Decode JWT (without verification)function decodeJWT(token) {const [header, payload] = token.split('.').slice(0, 2);return {header: JSON.parse(atob(header)),payload: JSON.parse(atob(payload))};}// Using jsonwebtoken library// npm install jsonwebtokenconst jwt = require('jsonwebtoken');const decoded = jwt.decode(token);const verified = jwt.verify(token, secret);
You May Also Like
What is a JWT?
A JWT (JSON Web Token, pronounced "jot") is like a digital passport. It's a compact, self-contained way to securely transmit information between parties.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Looks like gibberish? It's actually three base64-encoded parts separated by dots!
Why JWTs exist:
- Stateless authentication - No need to store sessions on the server
- Cross-domain - Works across different services
- Self-contained - All the info is in the token itself
- Compact - Small enough to send in headers/URLs
JWT Structure Explained
A JWT has three parts: Header.Payload.Signature
1. Header (Red part)
{
"alg": "HS256",
"typ": "JWT"
}
Tells us the token type and signing algorithm.
2. Payload (Purple part)
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022,
"exp": 1516242622
}
Contains the actual data (called "claims").
3. Signature (Blue part)
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
Verifies the token hasn't been tampered with.
Anyone can read a JWT! The payload is just base64-encoded, not encrypted. Never put sensitive data (passwords, credit cards) in a JWT.
Common JWT Claims
Registered Claims (Standard)
| Claim | Name | Description |
|---|---|---|
iss | Issuer | Who created the token |
sub | Subject | Who/what the token is about |
aud | Audience | Who should accept the token |
exp | Expiration | When the token expires (Unix timestamp) |
nbf | Not Before | Token not valid before this time |
iat | Issued At | When the token was created |
jti | JWT ID | Unique identifier for the token |
Common Custom Claims
{
"user_id": "12345",
"email": "[email protected]",
"roles": ["admin", "editor"],
"permissions": ["read", "write", "delete"]
}
How JWT Authentication Works
1. User logs in with credentials
┌──────┐ username/password ┌──────┐
│ User │ ───────────────────────→│Server│
└──────┘ └──────┘
2. Server creates and returns JWT
┌──────┐ JWT Token ┌──────┐
│ User │ ←───────────────────────│Server│
└──────┘ └──────┘
3. User sends JWT with every request
┌──────┐ Authorization: Bearer JWT ┌──────┐
│ User │ ────────────────────────────────→│Server│
└──────┘ └──────┘
4. Server verifies JWT and responds
┌──────┐ Protected Data ┌──────┐
│ User │ ←────────────────────────────────│Server│
└──────┘ └──────┘
Why this is better than sessions:
- Server doesn't need to store anything
- Works across multiple servers (microservices)
- Easy to scale horizontally
JWT Security Considerations
JWTs are not encrypted by default! Anyone can decode and read the payload. Only the signature prevents tampering.
Common JWT Vulnerabilities:
1. None Algorithm Attack
{"alg": "none"}
Attackers set algorithm to "none" to bypass signature verification. Fix: Always validate the algorithm on the server.
2. Secret Key Weakness Weak secrets like "secret" or "password" can be brute-forced. Fix: Use 256+ bit random keys.
3. Token Hijacking If an attacker steals your JWT, they become you. Fix: Use short expiration times, refresh tokens, and HTTPS.
4. No Expiration
Tokens that never expire are a security risk.
Fix: Always set exp claim (short-lived: 15min-1hour).
Security Best Practices:
- Use strong, random secret keys (256 bits minimum)
- Keep tokens short-lived (15 minutes for access tokens)
- Use refresh tokens for long sessions
- Always use HTTPS
- Validate all claims server-side
- Consider using RS256 (asymmetric) for distributed systems
JWT vs Session Cookies
| Feature | JWT | Session Cookies |
|---|---|---|
| Storage | Client (localStorage/memory) | Server (database/memory) |
| Scalability | Excellent (stateless) | Requires session sharing |
| Security | XSS vulnerable if in localStorage | CSRF vulnerable |
| Mobile | Easy to implement | Requires cookie handling |
| Size | Larger (self-contained) | Small (just session ID) |
| Revocation | Difficult (wait for expiry) | Easy (delete from store) |
When to use JWT:
- Single Page Applications (SPAs)
- Mobile applications
- Microservices architecture
- Third-party API authentication
When to use Sessions:
- Traditional web applications
- When you need instant revocation
- Sensitive applications (banking)
Debugging JWTs
Common Issues:
Token expired
{"exp": 1516239022} // Check if current time > exp
Invalid signature
- Wrong secret key
- Token was modified
- Algorithm mismatch
Token not yet valid
{"nbf": 1516239022} // Check if current time < nbf
Audience mismatch
{"aud": "https://api.example.com"} // Must match your API
Debugging Checklist:
- Decode the token (use this tool!)
- Check expiration time
- Verify the issuer
- Confirm the signing algorithm
- Validate the signature with your secret