Developer tools

JWT decoder

Paste a JSON Web Token to read its header and payload, see registered claims such as exp and iat as dates, and check whether it has expired. Decoding happens in this page, so production tokens do not leave your machine.

Decoding is not verification. This page does not check the signature, so it cannot tell you whether the token is genuine or has been tampered with.

Runs entirely in your browser. Nothing you enter here is uploaded.

How to decode a JWT

  1. Paste the token. A leading "Bearer " copied from an Authorization header is removed automatically.
  2. 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.
  3. The status line says whether the token has expired, is not yet valid, or has no expiry at all.
  4. 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

ClaimMeaning
isswho issued the token
subwho the token is about, usually a user ID
audwho the token is intended for
expexpiry time, in seconds since 1970 (NumericDate)
nbfthe token must not be accepted before this time
iatwhen the token was issued
jtia 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_wW1gFWFOEjXk

Its 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.

Sources and further reading

Guides that use this tool

↵ to open · Esc to close