How to Decode JWT (JSON Web Tokens) - Debugger Guide
Learn how to decode and debug JSON Web Tokens. View claims, expiration dates, headers, and signature details. Covers security pitfalls and our free JWT Decoder.
JSON Web Tokens (JWTs) are the passport of the modern web. They carry your identity, roles, and permissions securely between the client and the server.
But unlike a physical passport, you can’t just open a JWT and read it. It looks like a random string of characters: eyJhbGciOi...
In this guide, we’ll explain the structure of a JWT and show you how to decode it instantly with our Free JWT Decoder.
The 3 Parts of a JWT
A JWT is just three Base64-encoded strings joined by dots (.):
- Header: Metadata about the token (e.g., Algorithm: HS256).
- Payload: The actual data (User ID, Name, Expiration).
- Signature: A cryptographic hash to prevent tampering.
1. The Header
Usually contains the type (JWT) and the signing algorithm (HMAC SHA256 or RSA).
{
"alg": "HS256",
"typ": "JWT"
}
2. The Payload (Claims)
This is where the useful data lives. Standard fields (“claims”) include:
sub(Subject): User IDname: User’s Nameiat(Issued At): Timestampexp(Expiration): Timestamp
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
3. The Signature
The server takes the Header + Payload + Secret Key and hashes them. This ensures that if you change the Payload (e.g., change role: user to role: admin), the signature won’t match, and the server will reject it.
How to Debug JWTs
Developers often need to check:
- Is the token expired? Check the
expclaim. - Is the data correct? Verify the
suborrole. - Is the format valid? Ensure it has 3 parts.
Use our JWT Decoder to paste your token and see the decoded JSON instantly. It parses the Base64 encoding and formats the JSON for readability.
Manually Decoding a JWT
JWTs use Base64 URL encoding, not standard Base64. The difference:
+becomes-/becomes_- Padding (
=) is removed
Decode in JavaScript
function decodeJWT(token) {
const parts = token.split('.');
if (parts.length !== 3) throw new Error('Invalid JWT format');
// Decode header and payload (ignore signature)
const header = JSON.parse(atob(parts[0]));
const payload = JSON.parse(atob(parts[1]));
return { header, payload };
}
Decode in Python
import base64
import json
def decode_jwt(token):
parts = token.split('.')
if len(parts) != 3:
raise ValueError('Invalid JWT format')
# Decode header and payload
header = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))
payload = json.loads(base64.urlsafe_b64decode(parts[1] + '=='))
return header, payload
Note: Decoding isn’t the same as verifying. You can read the token’s contents, but you can’t trust them without verifying the signature.
Security Considerations
Never Trust Without Verifying
Decoding a JWT shows you what’s inside, but anyone can create a JWT with fake data. The signature is what proves authenticity.
To verify a JWT:
- Decode the header to find the algorithm (
alg) - Use the secret key (symmetric) or public key (asymmetric) to verify the signature
- If the signature is invalid, reject the token
Common JWT Vulnerabilities
1. Algorithm Confusion Attack
An attacker changes the alg from RS256 (asymmetric) to HS256 (symmetric). If your server blindly uses the algorithm in the header, it may treat the public key as the symmetric secret.
Defense: Hard-code the expected algorithm on the server. Never trust the alg field.
2. None Algorithm
The JWT spec allows "alg": "none" for unsigned tokens. An attacker could remove the signature and set alg to none.
Defense: Reject tokens with "alg": "none" in production.
3. Weak Secrets
If the HMAC secret is weak (e.g., “secret123”), attackers can brute-force it and forge tokens.
Defense: Use a strong, random secret (at least 256 bits). Store it securely (environment variables, secrets manager).
4. Token Leakage
JWTs are bearer tokens. Anyone with the token can use it until it expires. Common leak sources:
- Logs: Never log full JWTs.
- URLs: Avoid passing JWTs in query parameters (they appear in browser history and server logs).
- Local Storage: More vulnerable to XSS than cookies (though cookies have CSRF risks).
Defense: Use short expiration times (exp) and refresh tokens for long-lived sessions.
Claims You Should Validate
When verifying a JWT, check these standard claims:
| Claim | Name | Validation |
|---|---|---|
iss | Issuer | Match expected issuer (e.g., “https://yourapp.com”) |
aud | Audience | Match your application ID |
exp | Expiration | Reject if exp < current_time |
nbf | Not Before | Reject if current_time < nbf |
iat | Issued At | Verify timestamp is reasonable (not in the future) |
jti | JWT ID | Check against a blacklist for revoked tokens |
Real-World Use Cases
API Authentication
Instead of sessions, APIs issue JWTs. The client includes the token in the Authorization header:
GET /api/user/profile
Authorization: Bearer eyJhbGciOi...
The server decodes and verifies the token, then extracts the user ID from the payload.
Single Sign-On (SSO)
When you log in to Google and use that login for YouTube, Google Drive, etc., you’re using JWTs. Each service verifies the token issued by Google’s authentication server.
Microservices
In a microservices architecture, each service needs to know who the user is. JWTs allow stateless authentication: the token contains the user’s identity and permissions, so services don’t need to query a central database.
Temporary Access
APIs use JWTs to grant time-limited access. For example, a file upload service might issue a JWT that allows uploading to a specific bucket for 15 minutes.
Pro Tips
Use Libraries, Not Custom Code
Don’t write your own JWT verification logic. Use battle-tested libraries:
- JavaScript:
jsonwebtoken,jose - Python:
PyJWT,python-jose - Java:
jjwt,auth0-java-jwt - Go:
golang-jwt/jwt
These libraries handle edge cases and security issues you might miss.
Refresh Tokens
JWTs typically have short expiration times (15 minutes). To keep users logged in, use a refresh token:
- Issue a short-lived JWT (access token) and a long-lived refresh token
- When the JWT expires, the client sends the refresh token to get a new JWT
- If the refresh token is revoked (e.g., user logs out), they must re-authenticate
Revocation
JWTs can’t be revoked before expiration unless you maintain a blacklist. This defeats the purpose of stateless tokens. Solutions:
- Short expiration: Minimize the damage window
- Blacklist: Store revoked token IDs in a database
- Opaque tokens: Use random strings (sessions) for high-security scenarios
Debugging in Production
If a JWT fails to verify in production, check:
- Clock skew: Server clocks out of sync by more than the
leewayparameter - Key rotation: The token was signed with an old key that’s no longer trusted
- Algorithm mismatch: Token uses RS256 but server expects HS256
- Tampering: User edited the token manually
Token Size Considerations
JWTs can get large if you include too much data. A typical JWT is 200-1000 bytes. For comparison:
- Session ID: 20-40 bytes
- OAuth token: 40-80 bytes
Large JWTs impact:
- Network overhead: Every API request includes the full token
- Cookie limits: Browsers limit cookies to 4 KB
- Mobile data: Extra bytes on slow connections
Best Practice: Store only essential data in JWTs (user ID, role). Fetch additional data from the database as needed.
Frequently Asked Questions
Can I decode a JWT without the secret key?
Yes, you can decode the header and payload (they’re just Base64). But you can’t verify the signature without the key.
How long should JWTs be valid?
For access tokens, 15-60 minutes is common. For refresh tokens, days to months. Balance security (shorter is safer) with user experience (longer avoids frequent re-authentication).
Can I store JWTs in cookies?
Yes. Cookies can be more secure than Local Storage (use HttpOnly and Secure flags). But they’re vulnerable to CSRF attacks, so implement CSRF protection.
What is the difference between JWT and OAuth?
OAuth is an authorization framework that describes how to grant access. JWTs are a token format often used to implement OAuth. OAuth can use other token formats (like opaque tokens).
Are JWTs encrypted?
No, standard JWTs are signed (for integrity) but not encrypted. Anyone can read the payload. For sensitive data, use JWE (JSON Web Encryption).
Related Calculators
Related Articles
- Color Theory Basics for Web Design
Master color theory for web design including the color wheel, complementary palettes, WCAG contrast requirements, and color psychology to create effective interfaces.
- How to Minify CSS for Faster Websites
Learn what CSS minification does, why it speeds up your website, what it removes from your stylesheets, and best practices for minifying CSS in production.
- Cron Job Examples for Common Tasks (Copy-Paste Ready)
Practical cron job examples with clear explanations. Copy-paste ready crontab schedules for backups, reports, cleanup, monitoring, and automation tasks.
- Common JSON Syntax Errors and How to Fix Them
Fix JSON syntax errors fast with this developer guide. Learn the top 5 JSON parsing errors, before/after examples, and debugging techniques to validate JSON instantly.
Share this article
Have suggestions for this article?