JWT Decoder

Paste a JWT to decode its header and payload. All decoding runs in your browser — tokens never leave the page.

Enter input above to see the result.
Enter input above to see the result.
Enter input above to see the result.
This tool decodes only — it does not verify the signature against a key. Treat decoded payload as untrusted until verified.

Header, payload, signature

A JWT (JSON Web Token) is three base64url-encoded parts joined by dots: header.payload.signature. The header names the signing algorithm, the payload holds the claims (who the user is, what they can do, when the token expires), and the signature is a keyed hash that proves the token wasn't tampered with. This tool decodes the first two parts so you can see what's inside without the noise of base64 — useful when debugging auth flows, expired sessions, or "which user is this token for, exactly?".

Debugging auth with a decoded token

Registered claims at a glance

Decoded ≠ verified — and other trust boundaries

Algorithm confusion and the HS256/RS256 swap

A library configured to accept both HS256 (symmetric) and RS256 (asymmetric) can be tricked: an attacker takes the server's public key, signs a forged token with HS256 using that public key as the HMAC secret, and the misconfigured verifier accepts it. Always pin a single expected algorithm at verify time and reject tokens whose header specifies anything else.

Why JWTs don't revoke — and what to do about it

Issued tokens are valid until exp. Logging a user out, banning them, rotating keys — none of that invalidates an issued JWT without additional infrastructure (revocation lists, short expirations + refresh tokens, or stateful session lookup). If you need instant revocation, JWT alone is not the right mechanism; pair with a server-side check or use opaque tokens.

Keep PII out of the payload

The payload is Base64-encoded, not encrypted. Anyone who intercepts the token (browser dev tools, server logs, error trackers like Sentry that capture request headers) can read every field. Use minimal claims — user ID, role, expiry. Anything sensitive belongs in a server-side session lookup keyed by the token's sub. The header is also part of the signed payload — the signature covers base64url(header) + "." + base64url(payload) — but the vulnerabilities come from verifiers that pull the algorithm from the header before checking the signature.

An expired token, step by step

Paste a token whose three dot-separated parts decode to header {"alg":"HS256","typ":"JWT"} and payload {"sub":"1234567890","name":"Alice","iat":1700000000,"exp":1700003600}. The tool pretty-prints both JSON blocks, shows the third segment verbatim as the signature, and builds a summary line: alg: HS256 · exp: 2023-11-14 23:53:20Z ⚠ EXPIRED · iat: 2023-11-14 22:53:20Z · sub: 1234567890. The ⚠ EXPIRED flag appears because exp is compared against your browser's clock.

Decoder trust, clock skew, and JWE tokens

It decoded cleanly — does that mean the token is valid? No. Decoding only Base64-splits the three segments; the signature is never checked. A forged token decodes here exactly like a genuine one. Only a verifier holding the HMAC secret (HS256) or public key (RS256/ES256) can confirm authenticity — never trust a claim because "the decoder showed it."

Why is it flagged EXPIRED when my server still accepts it? The flag uses your device clock. Verifiers usually allow a few seconds of leeway for clock skew, so a token that's seconds past exp can still pass server-side while showing expired here.

The tool says "3 parts expected" for my token. You likely have a JWE (encrypted JWT), which has five dot-separated parts, or a malformed token. This decoder handles the signed JWS form (header.payload.signature) only; an encrypted payload can't be read without the decryption key anyway.

Is it safe to paste a real token? Decoding happens in your browser, but a live token is a bearer credential — anyone who sees it can impersonate the user until exp. Use a token from a test environment, and never paste production tokens into any tool, extension, or screen-share.

Three segments, two operations, one critical distinction

A JWT is three Base64url segments joined by dots: header.payload.signature. The header names the signing algorithm, the payload holds the claims (who, what, and expiry), and the signature is a keyed hash over the first two parts. Decoding the first two segments needs no key at all — they are merely encoded, not encrypted — which is why anyone can read a token's contents. The signature is the only part that proves the token wasn't tampered with, and verifying it requires the secret or public key. Reading a JWT and trusting a JWT are entirely different operations.

The "decoded means valid" trap

Assuming a JWT is secret or that decoding it means it's valid. The payload is plainly readable, so never put passwords or sensitive data in it. And this tool decodes — it does not verify the signature, so it cannot tell you a token is authentic or unexpired. Server-side you must always check the signature against your key and reject the dangerous alg: none, or an attacker can forge claims at will.

Related

Inspect the raw segments with the Base64 encoder, understand the signing hash via the hash generator, and read the exp claim with the timestamp converter. Why tokens aren't sessions: JWTs are not sessions.