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.
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
- Paste the access or ID token from a failing OAuth / OpenID Connect login — see what the IdP actually issued.
- Confirm token expiry: the tool decodes
expas a real date and flags it if it's in the past. - Sanity-check custom claims a backend is asserting (roles, permissions, tenant IDs).
- Read a token your library "rejected as invalid" to see whether the issue is structural, expiry, or signature.
Registered claims at a glance
iss— issuer (who created the token)sub— subject (the user/account it represents)aud— audience (who should accept it)exp— expiry (Unix timestamp)iat— issued-at (Unix timestamp)nbf— not-valid-before (Unix timestamp)
Decoded ≠ verified — and other trust boundaries
- A decoded JWT is NOT a verified JWT. The signature isn't checked here — that requires the issuer's public key (RSA/EC) or shared secret (HMAC). Decoded contents tell you what the token says, not whether you should trust it. Always verify on the server before honouring claims.
- Don't paste production tokens into anywhere. Anyone with a live JWT can impersonate the user until
exp. The browser doesn't transmit it from this tool, but extensions, screen-recordings, and dev tools can. Use a fresh token from a test environment if you need to share. alg: nonetokens are a known attack class. If a header hasalg: noneand your library accepts it, attackers can forge tokens. Reject this on the server.- Time skew matters. A token's
expis checked against the verifier's clock. Servers with drift fail tokens that look valid here.
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.