JSON Web Tokens (JWTs) are the backbone of modern authentication — used in OAuth2, OpenID Connect, API authorization, and session management across virtually every web platform. When something breaks — a 401 Unauthorized, an "invalid token" error, or an unexpected claim — being able to decode a JWT token and inspect its contents is an essential debugging skill.
Anatomy of a JWT
A JWT is three Base64URL-encoded strings joined by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
[HEADER].[PAYLOAD].[SIGNATURE]
Header
The header declares the token type and signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
Payload
The payload contains claims — key-value pairs of information about the user or session. Standard registered claims include:
{
"sub": "1234567890",
"iss": "https://auth.example.com",
"aud": "my-api",
"iat": 1516239022,
"exp": 1516242622,
"nbf": 1516239022,
"jti": "abc123"
}
Signature
The signature verifies the token has not been tampered with. For HS256 (HMAC-SHA256), it is computed as:
HMAC-SHA256(
base64url(header) + "." + base64url(payload),
secret
)
For RS256 (RSA), the signature is created with a private key and verified with the corresponding public key — enabling token issuers and verifiers to be separate services.
What a JWT Decoder Shows You
Decoding a JWT means Base64URL-decoding the header and payload sections. This requires no secret key — the payload is not encrypted, just encoded. Any JWT decoder (or even a simple Base64 decoder) can read the claims.
This is important: JWTs are encoded, not encrypted. Never store sensitive data like strong passwords or credit card numbers in a JWT payload unless you are using JWE (JSON Web Encryption), a different standard.
A good JWT decoder shows you:
- The decoded header (algorithm, token type, key ID)
- The decoded payload with all claims in human-readable JSON
- Expiration status — is the token expired right now?
- Human-readable timestamps for
iat,exp, andnbfclaims - The raw signature (for verification with the appropriate key)
Common JWT Debugging Scenarios
Token expired
The exp claim is a Unix timestamp. If exp is in the past, the server will reject the token. Decode the token and compare the exp value against the current time to confirm expiration.
// Check if a JWT is expired in JavaScript (without verification)
function isExpired(token) {
const payload = JSON.parse(
atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))
);
return payload.exp * 1000 < Date.now();
}
Wrong audience
The aud claim specifies which service the token is intended for. If your API checks audience and the token was issued for a different service, it will be rejected even if the signature is valid. Decode the token to verify the aud value matches your API's expected audience.
Algorithm confusion attacks
A known vulnerability involves changing the alg field in the header from RS256 to HS256, then signing with the server's public key (used as the HMAC secret). Servers that do not validate the algorithm field can be tricked into accepting forged tokens. Decoding the header reveals if someone has tampered with the algorithm claim.
Missing or wrong claims
Custom claims like role, permissions, or tenant_id are often the source of authorization bugs. Decoding the token immediately shows whether the claim is present and has the expected value.
Decoding JWTs Safely
When using an online JWT decoder, your primary concern should be privacy. JWTs from production systems contain user identifiers, roles, and sometimes email addresses. You should:
- Use a tool that processes tokens entirely in the browser — no server calls.
- Never paste production tokens with sensitive user data into any third-party tool you do not trust.
- For sensitive debugging, use the browser console directly.
JWT Algorithms at a Glance
- HS256 / HS384 / HS512 — HMAC with SHA. Symmetric: same secret for signing and verification. Simple but requires sharing the secret.
- RS256 / RS384 / RS512 — RSA signature. Asymmetric: private key signs, public key verifies. Allows public verification without sharing secrets.
- ES256 / ES384 / ES512 — ECDSA signature. Asymmetric, smaller keys and signatures than RSA with equivalent security.
- PS256 / PS384 / PS512 — RSA-PSS. Similar to RS but with probabilistic signing.
- none — No signature. Never use in production. Any server accepting this algorithm is critically vulnerable.
Decode Your JWT Now
Our free JWT decoder decodes tokens instantly in your browser. Paste any JWT to view the decoded header, payload claims, expiration status, and timestamp translations — with zero data sent to our servers.