JWT Tokens: What's Inside and How to Decode Them
JWT tokens look like gibberish but they're just base64-encoded JSON. Here's how to read them and a free decoder tool.
What Is a JWT (JSON Web Token)?
JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. JWTs are commonly used for authentication and authorization in modern web applications, particularly in stateless API architectures.
A JWT consists of three parts separated by dots: Header, Payload, and Signature. Visually, a JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT Structure Breakdown
1. Header
The header typically consists of two parts: the type of token (JWT) and the signing algorithm being used, such as HMAC SHA256 or RSA.
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload
The payload contains the claims — statements about an entity (typically the user) and additional data. There are three types of claims: registered, public, and private claims.
Common registered claims include:
- iss (issuer)
- exp (expiration time)
- sub (subject)
- aud (audience)
- iat (issued at)
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
3. Signature
To create the signature, you take the encoded header, encoded payload, a secret, and the algorithm specified in the header, and sign it.
HMACSHA256(
base64urlEncode(header) + "." + base64urlEncode(payload),
secret
)
Why You Need to Decode JWTs
Developers often need to decode JWTs during development and debugging for several reasons:
- Verify Claims: Ensure the token contains the expected user information and permissions
- Check Expiration: Validate that
expand other time-based claims are correct - Debug Authentication Issues: When login or API access fails, inspecting the JWT reveals what went wrong
- Security Auditing: Verify that sensitive data isn't improperly stored in the payload
- Test API Endpoints: Manually craft requests with decoded/modified tokens (in development only)
How to Decode a JWT
JWTs are encoded in Base64URL format. To decode a JWT, you need to:
- Split the token at each dot separator
- Base64URL-decode the first part to get the header
- Base64URL-decode the second part to get the payload
- The third part is the signature (verification requires the secret key)
Manual Decoding Steps
You can decode the header and payload in your browser's console:
// Decode JWT in browser console
function decodeJWT(token) {
const parts = token.split('.');
const header = JSON.parse(atob(parts[0]));
const payload = JSON.parse(atob(parts[1]));
return { header, payload };
const token = "your.jwt.token.here";
console.log(decodeJWT(token));
`
Important: The atob() function handles standard Base64, but JWT uses Base64URL (which replaces + with -, / with _, and removes padding =). For proper decoding, you'd need to convert Base64URL to standard Base64 first.
Using FreeToolJet's JWT Decoder
Our JWT Decoder tool simplifies this process:
- Paste your JWT into the input field
- Instantly see the decoded header and payload in a readable JSON format
- View all claims with proper formatting and syntax highlighting
- Check token expiration status at a glance
- No data leaves your browser — everything runs client-side
Step-by-Step Guide
- Open the JWT Decoder tool
- Copy your JWT from your application (usually from localStorage, sessionStorage, or Authorization header)
- Paste it into the decoder
- Review the decoded header and payload
- Verify claims, expiration, and structure
Security Considerations
⚠️ NEVER share JWTs containing real user data publicly. JWTs are bearer tokens — anyone who has the token can use it to access protected resources (until it expires).
Best Practices:
- Only decode JWTs in secure, private environments
- Don't log full JWTs in production applications
- Use JWT decoding tools only for development and debugging
- Remember: decoding a JWT does NOT verify its signature — verification requires the secret key
- Treat JWTs like passwords
Common JWT Debugging Scenarios
"Why is my API returning 401 Unauthorized?"
Decode the JWT and check:
- Is the exp (expiration) claim in the past?
- Is the iat (issued at) claim valid?
- Does the aud (audience) match your API?
"The user permissions look wrong"
Check the payload claims:
- Are the roles/permissions claims present?
- Are they in the expected format?
- Is the scope claim correct?
"The token works in development but not production"
Compare decoded JWTs from both environments:
- Are the iss (issuer) claims different?
- Are the signing algorithms (alg) the same?
- Are the audience (aud) values configured correctly?
JWT Signing Algorithms
Understanding the alg claim in the header is important:
| Algorithm | Description |
|---|---|
| HS256 | HMAC using SHA-256 (symmetric) |
| RS256 | RSA using SHA-256 (asymmetric) |
| ES256 | ECDSA using P-256 and SHA-256 |
| none | No signature (only for development, insecure) |
⚠️ Security Alert: The alg: "none" vulnerability allows attackers to bypass signature verification. Always validate the algorithm on the server side.
When NOT to Use JWT Decoding Tools
- Production debugging: Use proper logging and monitoring instead
- Sensitive production tokens: Decode in your local development environment only
- Tokens from unknown sources: Don't decode JWTs you don't understand
Related Tools
- JWT Decoder — Decode and inspect JSON Web Tokens
- JSON Formatter — Format and validate JSON data
- Base64 Encoder — Encode and decode Base64 strings
- Hash Generator — Generate secure hashes for tokens