How to Decode a JWT Token Online
How to Decode a JWT Token Online
JSON Web Tokens (JWTs) are everywhere in modern web development. If you're building APIs, handling authentication, or working with OAuth 2.0, you're dealing with JWTs daily. But when one shows up in a bug report or an API response and you need to inspect it fast, most developers just paste it into the first decoder they find on Google — without thinking about what that means for their security.
In this guide, we'll cover what JWTs actually are, how to decode them safely, and why the tool you use matters more than you think.
What Is a JWT?
A JWT is a compact, URL-safe token used to represent claims between two parties. It looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
It has three parts separated by dots:
- Header — Algorithm and token type (Base64URL encoded)
- Payload — The claims/data (Base64URL encoded)
- Signature — Used to verify the token wasn't tampered with
The header and payload are just Base64URL encoded JSON — they are not encrypted. Anyone can decode and read them. The signature is what proves the token is legitimate.
Decoding the Header
The first part of a JWT is always the header. Decoded, it looks like:
{
"alg": "HS256",
"typ": "JWT"
}
The alg field tells you which algorithm was used to sign the token. Common values include HS256 (HMAC-SHA256), RS256 (RSA-SHA256), and ES256 (ECDSA). If you ever see alg: none — treat that token as suspicious. A none algorithm means the signature is skipped entirely, which is a known vulnerability.
Decoding the Payload
The payload contains the claims. A typical payload looks like:
{
"sub": "1234567890",
"name": "John Doe",
"email": "john@example.com",
"iat": 1516239022,
"exp": 1716239022,
"roles": ["admin", "user"]
}
Key fields to look for:
- sub — Subject (usually user ID)
- iat — Issued at (Unix timestamp)
- exp — Expiry (Unix timestamp) — check if this has passed
- iss — Issuer
- aud — Audience
The exp field is critical when debugging authentication issues. If a user is getting 401 errors, the first thing to check is whether the token has expired.
Why the Tool You Use Matters
Here's the part most tutorials skip. When you paste a JWT into an online decoder, you need to think about what that token contains and where it's being sent.
If your token contains user IDs, email addresses, or role claims, and you paste it into a tool that sends it to a remote server for decoding — you've just leaked that data to a third party. Even production tokens are sometimes accidentally pasted into these tools during debugging.
The safe approach: Use a decoder that runs entirely in your browser with no server-side processing.
Konvertio's JWT Decoder decodes and verifies JWT tokens entirely client-side using your browser's Web Crypto API. Nothing you paste is ever sent anywhere. You can even paste production tokens safely.
It also shows:
- Decoded header and payload with syntax highlighting
- Token expiry status (expired / valid / soon to expire)
- Signature algorithm
- Human-readable timestamps for iat and exp
Verifying the Signature
Decoding is easy — anyone can Base64 decode a JWT. Verifying the signature is what actually proves the token is legitimate.
To verify, you need the secret key (for HS256) or the public key (for RS256/ES256). Most online decoders let you paste the secret and will verify the HMAC signature locally.
If you're working with RS256 tokens (common in Auth0, Firebase, Okta, AWS Cognito), the public key is usually available at a /.well-known/jwks.json endpoint. You can paste that public key into the verification field to confirm the signature.
Common JWT Debugging Scenarios
"Invalid token" errors
- Check if the token is malformed (missing dots, extra whitespace)
- Check the exp claim — token may be expired
- Check the aud claim — your API may be rejecting wrong audience
- Check the algorithm matches what your server expects
"Token expired" errors
- Decode the token and look at the exp field. Convert the Unix timestamp to a human date. If it's in the past, the client needs to refresh the token.
"Signature verification failed"
- The token was tampered with, or the wrong secret was used to sign it. This is a security alert — investigate how the token was generated.
Quick Reference: JWT Claims
| Claim | Meaning | Example |
|---|---|---|
| sub | Subject (user ID) | "12345" |
| iss | Issuer | "https://auth.example.com" |
| aud | Audience | "https://api.example.com" |
| exp | Expiry | 1716239022 |
| iat | Issued at | 1516239022 |
| nbf | Not before | 1516239022 |
| jti | JWT ID (unique ID) | "abc123" |
Wrapping Up
JWTs are simple to decode but easy to mishandle. Always use a tool that processes tokens locally — especially if you're working with production data.
Try Konvertio's JWT Decoder — it's free, runs entirely in your browser, and supports both decoding and signature verification.
Try other developer tools, including Base64 encoding, hash generation, and UUID creation.
Q&A
What exactly is a JWT, and how is it structured?
A JWT is a compact, URL-safe token for transmitting claims. It has three Base64URL parts separated by dots: header (algorithm and type), payload (claims like sub, exp, iss, aud), and signature (to prove integrity). The header and payload are only encoded, not encrypted — anyone can decode them — while the signature prevents tampering.
Is it safe to paste my JWT into an online decoder?
Only if the tool runs entirely in your browser with no server-side processing. Many online decoders send your token to a remote server, which can leak user IDs, emails, or roles. A safer option is a client-side tool like Konvertio's JWT Decoder, which uses the browser's Web Crypto API and never transmits your token — safe even for production tokens.
What does alg: none mean in a JWT header?
It means no signature is applied, so the token isn't cryptographically protected. This is a known vulnerability pattern; treat tokens with alg: none as suspicious and do not accept them unless you explicitly and securely allow unsigned tokens (which most systems should not).
How do I verify a JWT's signature (HS256 vs RS256/ES256)?
For HS256, you need the shared secret to verify the HMAC signature. For RS256/ES256, you need the issuer's public key, typically available at a /.well-known/jwks.json endpoint (common with Auth0, Firebase, Okta, AWS Cognito). Paste the appropriate key into your verifier; many tools (including Konvertio's) perform verification locally.
I'm seeing "Invalid token," "Token expired," or "Signature verification failed." What should I check?
- Invalid token: Ensure it has three parts (two dots) and no extra whitespace; confirm alg matches server expectations; check aud is correct.
- Token expired: Decode and check exp; if it's in the past, refresh the token.
- Signature verification failed: The token may be tampered with or signed with the wrong key/secret — treat this as a security alert and investigate the token's origin.