JWT Decoder
Decode JWT tokens locally and view header, payload, and expiry information.
How JWT decoding works
JWT tokens consist of three Base64-encoded parts separated by dots: header, payload, and signature. This decoder reads the header and payload without verifying the signature, allowing you to inspect token contents locally.
Introduction
JSON Web Tokens are the backbone of modern authentication — every login flow, API call, and single sign-on system uses them. But a JWT is just three Base64URL-encoded segments separated by dots: header, payload, and signature. This tool decodes the header and payload into readable JSON, revealing the signing algorithm, token claims, expiration time, and embedded user data. Whether you're debugging an authentication issue, verifying token claims, or learning how JWTs work, this decoder gives you instant visibility into what a token actually contains — without running it through a backend server.
What This Tool Does
Why It Matters
JWT tokens carry identity, permissions, and expiration data that control access to your systems. A misconfigured token with the wrong algorithm, expired timestamp, or excessive permissions creates a direct security vulnerability. The 2022 OWASP API Security Top 10 lists Broken Object Level Authorization (BOLA) as the #1 risk — often caused by trusting JWT claims without verification. Decoding tokens reveals whether the algorithm is secure (RS256 vs none), whether the expiration is reasonable, and whether the claims match what you expect. This visibility is essential for security audits, incident response, and understanding authentication flows.
How It Works
Step-by-Step Examples
Paste the complete JWT token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
The tool splits the token at . separators and Base64URL-decodes each segment
Read the decoded header: {"alg": "HS256", "typ": "JWT"}
Read the decoded payload: {"userId": "1234567890", "role": "admin", "exp": 1700000000}
Header: {alg: 'HS256', typ: 'JWT'} | Payload: {userId: '1234567890', role: 'admin', exp: 1700000000} | Signature: verified separatelyPaste a JWT with an unusual algorithm: eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0...
The decoded header reveals: {"alg": "none", "typ": "JWT"}
Recognize that algorithm 'none' means the token has no signature verification — anyone can forge it.
This is a critical vulnerability: tokens with alg:none bypass all authentication checks
WARNING: algorithm 'none' detected — this token is unsigned and can be forged by anyoneCode Examples
function decodeJWT(token) {
const parts = token.split('.');
if (parts.length < 2 || parts.length > 3) {
throw new Error('Invalid JWT: expected 2 or 3 parts');
}
function base64URLDecode(str) {
let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
while (base64.length % 4) base64 += '=';
return JSON.parse(decodeURIComponent(
atob(base64).split('').map(c =>
'%' + c.charCodeAt(0).toString(16).padStart(2, '0')
).join('')
));
}
const header = base64URLDecode(parts[0]);
const payload = base64URLDecode(parts[1]);
const signature = parts[2] || null;
// Check expiration
const now = Math.floor(Date.now() / 1000);
const isExpired = payload.exp ? payload.exp < now : false;
const isNotYetValid = payload.nbf ? payload.nbf > now : false;
return {
header,
payload,
signature,
isExpired,
isNotYetValid,
expiresIn: payload.exp ? payload.exp - now + ' seconds' : 'no expiration set'
};
}
// Usage
const token = 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIn0.signature';
const decoded = decodeJWT(token);
console.log(decoded.header); // { alg: 'HS256' }
console.log(decoded.payload); // { userId: '1234567890' }
console.log(decoded.isExpired); // true or falsefunction verifyJWTClaims(token, expected) {
const decoded = decodeJWT(token);
const errors = [];
// Verify algorithm
if (expected.alg && decoded.header.alg !== expected.alg) {
errors.push(`Algorithm mismatch: expected ${expected.alg}, got ${decoded.header.alg}`);
}
// Reject 'none' algorithm
if (decoded.header.alg === 'none') {
errors.push('Insecure algorithm: none — token is unsigned');
}
// Verify audience
if (expected.aud) {
const audiences = Array.isArray(decoded.payload.aud)
? decoded.payload.aud : [decoded.payload.aud];
if (!audiences.includes(expected.aud)) {
errors.push(`Audience mismatch: expected ${expected.aud}`);
}
}
// Verify expiration
const now = Math.floor(Date.now() / 1000);
if (decoded.payload.exp && decoded.payload.exp < now) {
errors.push(`Token expired ${now - decoded.payload.exp} seconds ago`);
}
// Verify issuer
if (expected.iss && decoded.payload.iss !== expected.iss) {
errors.push(`Issuer mismatch: expected ${expected.iss}, got ${decoded.payload.iss}`);
}
return { valid: errors.length === 0, errors, decoded };
}
// Usage
const result = verifyJWTClaims(token, {
alg: 'RS256',
aud: 'api.example.com',
iss: 'auth.example.com'
});
console.log(result.valid); // true or false
console.log(result.errors); // list of validation failuresJWT Header Fields
| Field | Values | Security Implication |
|---|---|---|
| alg | HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, none | 'none' is insecure — bypasses signature verification |
| typ | JWT, at+jwt | Token type identifier |
| kid | Key ID string | Indicates which signing key was used |
| jku | JWK Set URL | URL of the key set — verify this matches your trusted issuer |
Common JWT Payload Claims (Registered)
| Claim | Full Name | Type | Purpose |
|---|---|---|---|
| iss | Issuer | String/URI | Who issued the token |
| sub | Subject | String | Who the token is about (user ID) |
| aud | Audience | String/Array | Who the token is intended for |
| exp | Expiration Time | Numeric (Unix) | When the token expires |
| nbf | Not Before | Numeric (Unix) | When the token becomes valid |
| iat | Issued At | Numeric (Unix) | When the token was created |
| jti | JWT ID | String | Unique token identifier for revocation |
Benefits
- Instantly decodes JWT header and payload into readable JSON without backend verification.
- Detects insecure algorithms (none, HS256 when RS256 expected) that enable token forgery.
- Calculates token expiration status and time remaining for debugging authentication flows.
- Fully client-side — token data never leaves the browser, suitable for inspecting sensitive production tokens.
Use Cases
Debugging authentication failures by inspecting JWT claims, expiration, and algorithm configuration.
Security auditing of JWT tokens to verify the signing algorithm matches expected security requirements.
Learning JWT structure by visualizing how header, payload, and signature segments encode data.
Verifying token claims (audience, issuer, subject) before trusting them in authorization decisions.
Common Mistakes to Avoid
Trusting the decoded payload without verifying the signature — anyone can forge the header and payload of an unsigned token.
Ignoring the 'alg' header — if it says 'none', the token has no signature and is trivially forgeable.
Not checking token expiration — a valid signature does not mean the token is still authorized to be used.
Using HS256 (symmetric) when RS256 (asymmetric) is expected — the client should not have the signing key.
Security Implications
A JWT decoder reveals the plaintext content of tokens, including user IDs, roles, permissions, and expiration times. Never log decoded JWT payloads in production systems — they may contain PII or session data. The most critical security field is the 'alg' header: algorithm 'none' bypasses signature verification entirely, allowing anyone to forge valid-looking tokens. The 2015 auth0 vulnerability (CVE-2015-9284) exploited algorithm confusion between HS256 and RS256 to bypass signature verification. Always verify the algorithm matches your expected value before trusting any JWT claims.
Security Information
Frequently Asked Questions
References & Further Reading
What is a JSON Web Token (JWT)?
A JSON Web Token (JWT) is a compact, URL-safe means of representing claims between two parties. JWTs are widely used for authentication and authorization in modern web applications. A JWT consists of three parts: the header (algorithm and token type), the payload (claims and user data), and the signature (for verification).
JWTs are self-contained, meaning they carry all necessary information within the token itself. This eliminates the need for session storage on the server, making JWTs ideal for stateless authentication in distributed systems. Our decoder lets you inspect any JWT's contents without exposing it to third-party services.
Understanding JWT Structure
A JWT consists of three Base64URL-encoded parts separated by dots: header.payload.signature. The header specifies the signing algorithm (e.g., HS256, RS256) and token type. The payload contains claims like sub (subject), exp (expiration), iss (issuer), and custom data.
The signature is created by signing the encoded header and payload with a secret key (for HMAC) or a private key (for RSA/ECDSA). This signature allows the recipient to verify that the token has not been tampered with. Anyone can decode a JWT to read its contents, but only someone with the signing key can create or modify a valid token.
Our decoder performs Base64URL decoding on each part and displays the parsed JSON. This is a read-only operation that does not verify the signature. For signature verification, you need access to the signing key, which is why our tool focuses on decoding rather than verification.
Real-World JWT Applications
Authentication Tokens: After a user logs in, the server issues a JWT containing user identity and permissions. The client includes this token in subsequent requests, eliminating the need for server-side session storage.
API Authorization: APIs use JWTs to verify that requests come from authenticated users with the necessary permissions. The token's claims specify what actions the user is authorized to perform.
Single Sign-On (SSO): JWTs enable SSO across multiple applications. A user authenticates once and receives a JWT that works across all connected services, improving user experience while maintaining security.
Microservices Communication: In microservices architectures, JWTs allow services to verify user identity without calling a central authentication service. Each service can independently validate the token using the shared public key.
Common JWT Security Mistakes
Storing Sensitive Data in Payload: JWT payloads are Base64URL-encoded, not encrypted. Anyone can decode and read the payload. Never store passwords, credit card numbers, or other sensitive data in JWT claims. Use the payload only for non-sensitive metadata.
Missing Expiration Claims: Tokens without an exp claim remain valid indefinitely. Always set appropriate expiration times. Short-lived tokens (15-60 minutes) reduce the window of opportunity if a token is compromised.
Using "alg: none": Some JWT libraries allow the "none" algorithm, which skips signature verification entirely. This is a critical vulnerability that allows token forgery. Always ensure your JWT library rejects unsigned tokens.
Weak Secret Keys: HMAC-based JWTs are only as secure as the secret key. A short or predictable key can be brute-forced. Use cryptographically random keys of at least 256 bits for HS256.
Related Authentication Tools
Explore these authentication and cryptographic tools:
- HMAC Generator — Generate HMAC signatures for JWT authentication.
- Secret Token Generator — Generate secure keys for JWT signing.
- SHA-256 Generator — Generate hashes used in JWT signature verification.
- Encoding Utilities — Understand Base64URL encoding used in JWTs.
- Password Strength Checker — Verify the strength of passwords used with JWT authentication.