EveryToolAI
Index

JWT Decoder

A JWT decoder splits a JSON Web Token at its two dots and Base64url-decodes the first two parts, so you can read the claims inside — who the token is for, when it expires, and what it grants. This decoder runs entirely in your browser: the token is never uploaded, logged or stored, which matters because a JWT is a live credential for as long as it is valid.

updated

Decoded locally in your browser — the token is never sent anywhere. The signature is not verified: decoding shows the claims, it does not prove they are authentic.

header
{
  "alg": "HS256",
  "typ": "JWT"
}
payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

How a JWT is put together

A JSON Web Token is three Base64url-encoded strings joined by dots: header, payload and signature. The header names the signing algorithm — typically HS256 or RS256 — and the token type. The payload holds the claims: the statements the issuer is making about the subject. The signature is a cryptographic check over the first two parts.

The important thing, and the part that surprises people, is that the first two parts are only encoded, not encrypted. Base64url is a transport format, not a secret. Anyone holding a token can read its payload with no key at all — which is exactly what this page does, and why you must never put a password, a private key or anything else sensitive into a JWT payload.

Decoding here happens in your browser: the token is split on the dots, each part is padded back to a multiple of four characters, decoded with the browser's own Base64 support, and parsed as JSON. No request is made. You can load this page, disconnect from the network, and decode a token with your Wi-Fi off — which is the simplest proof that the token never went anywhere.

A worked example

The canonical sample token used throughout the JWT documentation is three short strings joined by two dots. It is worth reading once slowly, because every token you meet afterwards has the same shape. Decoded, its header and payload look like this:

The sample token, decoded
header   {"alg":"HS256","typ":"JWT"}
payload  {"sub":"1234567890","name":"John Doe","iat":1516239022}
sig      43 base64url chars -> 32 raw bytes (HMAC-SHA256)

That iat value is a Unix timestamp: 1516239022 seconds after the epoch, which is 18 January 2018 at 01:30:22 UTC. Timestamps in JWTs are always seconds, never milliseconds — a frequent source of tokens that appear to expire fifty thousand years in the future. The signature decodes to exactly 32 bytes because HMAC-SHA256 produces a 256-bit output.

A real production token is longer but no more mysterious. Alongside the registered claims below you will usually find whatever your identity provider chose to add — scope or permissions, a tenant or organisation id, an email, sometimes a role. Those custom names are not standardised, so two providers will spell the same idea differently.

Most of what you will read, though, comes from a small set of registered claim names. They are three letters each, and they are worth knowing by sight:

Registered JWT claims (RFC 7519)
ClaimNameWhat it means
issIssuerWho minted the token
subSubjectWho or what it is about — usually a user id
audAudienceWhich service is allowed to accept it
expExpirationUnix seconds after which it must be rejected
nbfNot beforeUnix seconds before which it must be rejected
iatIssued atUnix seconds when it was minted
jtiJWT IDUnique id, used to revoke or de-duplicate

Is it safe to paste a JWT into an online decoder?

It depends entirely on where the decoding happens, and most decoders do not tell you.

A JWT is a bearer credential. That is the whole design: whoever holds the token can act as its subject, with its scopes, until it expires — no password, no second factor. A production access token pasted into a page that sends it to a server has been handed to a third party you have not audited, and it stays valid for as long as its exp says. If that token belonged to a customer or an admin account, you have created a real incident, and one that is genuinely difficult to notice afterwards.

Plenty of popular decoders are server-side. The token goes into a form, the form posts it, and a backend returns the decoded JSON. It may be logged in an access log, held in an error tracker, or cached. None of that is necessarily malicious — it is simply how the page was built — but it is indistinguishable from the outside.

This page decodes in the browser, and you do not have to take our word for it. Open your developer tools, switch to the Network tab, paste a token and watch: nothing is sent. Or load the page, turn off your Wi-Fi, and decode anyway. Either check takes ten seconds and settles the question for any tool, including this one.

Two habits are worth keeping regardless. Prefer an expired or test token when you only need to see the shape of a payload. And if you have already pasted a live production token into a tool you are unsure about, rotate it — revoking one token is cheap, and finding out later that it was retained is not.

What this decoder deliberately does not do

It does not verify the signature. Verification needs the shared secret or the issuer's public key, and neither belongs in a web page — a public tool that asks you for your signing secret is asking for the one thing that lets it mint tokens of its own. Signature verification is a server-side job, done by your auth library, against a key you control. This tool reads the token; it does not tell you whether to trust it.

That distinction matters more than it sounds. A decoded payload showing role: admin proves nothing on its own — anyone can craft that payload and Base64url-encode it. Only a verified signature makes a claim trustworthy.

It also cannot read an encrypted token. JWE tokens have five parts rather than three and their payload is genuinely ciphertext, so there is nothing to display without the decryption key. Nested tokens — a JWT carried inside another JWT — decode one layer at a time; paste the inner token back in to go deeper. Malformed input gets a plain error rather than a partial guess, because a half-decoded credential is worse than none.

Frequently asked questions

Does this verify the JWT signature?

No. It decodes the header and payload so you can read the claims, but it does not check the signature. Verification requires the shared secret or the issuer's public key, and that should happen on your server with a real auth library — never in a public web tool that would have to be handed the key.

Is it safe to paste my token here?

Decoding happens entirely in your browser and the token is never transmitted or stored, so yes. You do not have to take that on trust: open the Network tab and watch nothing get sent, or disconnect from the internet and decode anyway. Treat every JWT as a live credential and apply the same check to any other tool.

Why can anyone decode a JWT without a password?

Because the payload is Base64url-encoded, not encrypted — it is readable by design so that any service in the chain can inspect the claims. The signature protects against tampering, not against reading. This is why a JWT payload must never contain a password, a key or anything else you would not put in a log line.

What do exp, iat and nbf mean?

They are timestamps, all in Unix seconds. exp is the moment after which the token must be rejected, iat is when it was issued, and nbf is a start time before which it is not yet valid. Seconds, not milliseconds — a token whose exp looks like it lands in the year 50,000 is almost always a milliseconds value in a seconds field.

My token has five parts instead of three. Why won't it decode?

Five parts means it is a JWE — an encrypted token rather than a signed one. Its payload is real ciphertext, so there is nothing readable to show without the decryption key. Signed JWTs (JWS), the kind almost all APIs issue, have exactly three parts and two dots.

Can I decode a token without an internet connection?

Yes, and it is the quickest way to prove the claim on this page. Load the tool once, turn off your Wi-Fi, then paste a token — it still decodes, because the decoding was always happening on your device. Nothing about this page needs a server after the initial load.

Related tools