StringMash.com

JWT decoder

Read a token's header and payload, with its claims explained. Nothing leaves your browser.

187 characters
Updates as you type
Claims are explained below

Show the steps
  1. Split at the dots: a header of 36 characters, a payload of 122 and a signature of 27.
  2. The header and payload are base64url: decode each, and the result is JSON.
  3. The header says it was signed with HS256 and its type is JWT.
  4. sub is the subject, usually the user it is about: 1234567890.
  5. iat is the time it was issued. It's 1767225600 seconds after 1 January 1970, which is 2026-01-01 00:00:00 UTC.
  6. exp is the expiry time, on or after which it must not be accepted. It's 4102444800 seconds after 1 January 1970, which is 2100-01-01 00:00:00 UTC. It hasn't expired yet.
  7. The third part is the signature. Checking it needs the secret or public key, which this page doesn't ask for: decoding a token shows what it says, not whether it's genuine.

Using the decoder

Paste a token and its header and payload appear as formatted JSON. A Bearer prefix copied from an Authorization header is fine; it's ignored. Show the steps explains each standard claim, turns the dates into UTC, and says whether the token has expired.

The decoding happens in your browser. A token is often a working password for whatever issued it, so this page never sends it anywhere.

What's in a JWT

A JSON Web Token is three parts joined by dots. The first is the header, which says how the token is signed. The second is the payload, the claims the token makes about someone. The third is the signature. The first two are JSON encoded with base64url, which is Base64 with - and _ in place of + and /, and the padding left off.

Base64url isn't encryption. Anyone holding a token can read its payload, which is exactly what this page does, so a JWT shouldn't carry anything secret. The signature stops it being changed, not read.

The standard claims

RFC 7519, the standard that defines JWTs, registers seven claim names. iss is who issued the token, sub is who it's about, and aud is who it's meant for. exp is when it expires, nbf the time before which it mustn't be accepted, and iat when it was issued. jti is a unique ID for the token.

The three times are NumericDates: the number of seconds since midnight UTC on 1 January 1970. 4102444800, for instance, is the first second of 2100. Anything else in the payload, like a name or a role, is up to whoever made the token.

Decoding isn't verifying

Checking a signature needs the secret it was signed with, or the issuer's public key, and this page deliberately doesn't ask for either. So a token decoded here might have been made up: decoding shows what it says, not who said it. A header with alg set to none means the token isn't signed at all, and the steps point that out.

The standard suggests saying JWT the same way as the English word jot. It was published in May 2015.

Questions

Is it safe to paste a real token here?

The token is decoded in your browser and never sent to a server. Even so, treat a live token like a password: anyone who has it can use it until it expires.

Why does it say the token has expired?

Its exp claim is a time in the past, compared with your device's clock. Servers reject a token on or after that time.

Can it decode an encrypted token?

No. An encrypted token, a JWE, has five parts instead of three, and its contents can only be read with the key it was encrypted for.

Can I make or sign a JWT here?

No. Signing needs a key, and a page that asks for your signing key is one to be wary of.