How to decode a JWT
- Paste the token. A leading "Bearer " copied from an Authorization header is removed automatically.
- The header and payload appear as formatted JSON. Standard claims are labelled, and time claims (exp, nbf, iat) are shown both as the raw number and as a UTC date.
- The status line says whether the token has expired, is not yet valid, or has no expiry at all.
- Warnings appear for risky tokens, such as one whose algorithm is "none".
What is inside a JWT
A JSON Web Token (RFC 7519) is three Base64url-encoded parts joined by dots. The header is a small JSON object naming the signing algorithm (alg) and usually the type (typ). The payload is a JSON object of claims — statements about the user or session. The signature is computed over the first two parts with a secret or private key.
Decoding is only Base64url decoding and JSON parsing: no key is involved. That is why this tool can do it, and also why anyone who obtains a token can read it. Never put secrets such as passwords in a JWT payload.
Registered claims
| Claim | Meaning |
|---|---|
| iss | who issued the token |
| sub | who the token is about, usually a user ID |
| aud | who the token is intended for |
| exp | expiry time, in seconds since 1970 (NumericDate) |
| nbf | the token must not be accepted before this time |
| iat | when the token was issued |
| jti | a unique ID, used to prevent replay |
Why decoding is not verifying
Checking a token means recomputing the signature with the issuer's key and comparing it, then checking exp, nbf, iss and aud against what your application expects. A decoder that shows a valid-looking payload proves nothing: anyone can create a token with any payload. Servers should also reject "alg": "none" and should not let the token's own header choose the verification algorithm — both are well-known attack routes described in RFC 8725, the JWT best-practice guide.
Example
RFC 7519 section 3.1 contains this example token (line breaks added for display):
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXkIts header decodes to {"typ":"JWT","alg":"HS256"} and its payload to {"iss":"joe","exp":1300819380,"http://example.com/is_root":true}. The exp value 1300819380 is 22 March 2011 at 18:43:00 UTC, so the tool reports the token as expired. The custom claim http://example.com/is_root shows that claim names can be URIs to avoid collisions.
Inputs that are not tokens get specific messages: "abc.def" has only two parts; a token whose first part contains characters outside the Base64url alphabet fails at the header; a token whose payload decodes to plain text rather than a JSON object fails at the payload.
Limits
- No signature verification, as explained above. Use your JWT library on the server for that.
- Encrypted tokens (JWE) have five parts and an encrypted payload; they cannot be read without the key, and this tool reports them as having the wrong number of parts.
- Clock skew. Expiry is compared with your device's clock. Servers usually allow a minute or two of leeway, so a token that just expired here may still be accepted there.
Frequently asked questions
Is it safe to paste a real token here?
The token is decoded in your browser and never sent over the network. Still, treat live tokens as passwords: clear the box when you are done, and prefer expired or test tokens where you can.
Can this tool verify the signature?
No. Verification needs the issuer's secret or public key. This page only decodes the token so you can read it.
How do I read the exp value?
It is the number of seconds since 1 January 1970 UTC. The tool shows it as a date next to the raw number.
What does "alg": "none" mean?
The token is unsigned. It should never be accepted as proof of identity.
Why can anyone read my JWT?
Because the header and payload are only Base64url-encoded, not encrypted. The signature prevents changes, not reading.