Skip to content

JWT decoder

Runs in your browserNothing is uploadedThis runs entirely in your browser. Nothing is uploaded.

Paste a JWT to see its header and payload formatted, with issue and expiry times converted to readable dates. The signature is not verified, and the page says so.

Input

⚠️ This tool does not verify signatures — that needs the issuer’s key, which is not here. Being readable does not make a token valid.

A leading “Bearer ” is accepted.

⚠️ Avoid pasting production tokens. This tool does not send them, but the value is a credential and it lingers in screen shares, recordings and history.

Output

Paste a token and its header, payload and expiry verdict appear here.
Pasted tokeneyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJl….dBjftJeZ4CVP…Decodedalg: HS256sub: "123"exp: 2026-09-05 09:00(expired)The signature is not verified — that needs the key — and the page says so.
A JWT header and payload are not encrypted, only Base64URL-encoded. Anyone holding the token can read them, which is why secrets must never go in the payload.
All tools

Why this one

Times you can actually read
exp, iat and nbf arrive as Unix seconds. They are converted to dates and compared against the current time, so you get “expired” or “still valid” rather than a number.
Non-ASCII claims survive
Base64 decoding yields bytes; without re-decoding as UTF-8, names in Japanese or accented text turn to mojibake. This decodes properly.
Honest about what it cannot do
Verifying a signature needs the issuer’s key, which this tool does not have. That “readable” is not “valid” is shown above the result, always, and an `alg: none` token gets its own warning.

How to use it

  1. Paste the token

    A leading “Bearer ” is fine — it is stripped.

  2. Read the contents

    Header and payload are formatted. Date claims are converted below.

  3. Check the expiry

    If the token carries one, its state against the current time is shown at the top.

Terms and how to read them

The three parts
Header, payload and signature, separated by dots. The first two are plain base64url and readable by anyone — which is why secrets must never go in the payload.
exp / iat / nbf
Expiry, issued-at and not-before. All are Unix seconds — seconds since 1 January 1970.
alg
The signing method. HS256 is a shared secret, RS256 is public key. `none` means unsigned — anyone can forge such a token if the receiver accepts it.
sub / aud / iss
The subject the token is about (usually a user id), the audience allowed to accept it, and the issuer that minted it. When authentication fails, check aud and iss against the receiver’s configuration first — a mismatch there rejects tokens well before expiry does.
Why base64url rather than base64
Because a JWT is meant to travel in URLs and HTTP headers, where base64’s `+`, `/` and `=` already mean other things. The url variant substitutes `-` and `_` and drops the padding. That difference is why a generic base64 decoder sometimes refuses one.
kid in the header
The name of the key used to sign. Issuers that rotate between several keys expect the receiver to pick by this name. When authentication breaks midway through a key rotation, check whether kid still points at the retired key.

Questions

Is the token sent anywhere?
No. It is base64-decoded and formatted entirely in the browser.
Can I paste a production token?
This tool will not send it, but it is still unwise. A JWT is a credential, and it lingers in screen shares, recordings and browser history. Use an expired or test token.
Can it check the signature?
No. That needs the issuer’s key, and there is no mechanism here to hold one. Verification belongs on the server receiving the token.
It decodes fine but authentication fails.
Readable and valid are different things. Suspect expiry, a mismatched audience or issuer, or a signature that does not check out.
Is the content encrypted?
No. A signature shows the token was not altered in transit; it does not hide anything. Header and payload are readable by anyone who base64url-decodes them. If a value has to stay secret, either use the encrypted variant of the spec (JWE) or keep it out of the token and look it up server-side.
I logged out and the token still works.
A JWT is valid from issue until expiry by design; there is no built-in way to revoke one. Invalidating on logout requires the receiver to keep a revocation list, or a short expiry paired with refresh tokens. This is a property of the specification rather than a bug in an implementation.
Can this tell me whether the token has expired?
It shows exp as a readable date, so comparing it with now answers the question. The actual decision belongs to the receiving server, though, and its clock may differ from your device’s. Do not settle a borderline case from this screen alone.
Sponsored links