JWT Decoder
Decode a JSON Web Token and read what is actually in it — claims explained, expiry checked against your clock. It runs in your tab and the token never leaves it.
Token
This runs in your tab. Nothing is uploaded, and there is deliberately no box for a signing secret — see below for why.
Decoded
Why this one has no “secret” box
Most JWT tools online offer a field for your signing key so they can verify the signature. That is a bad trade. A leaked token is one compromised session that expires on its own; a leaked signing key lets an attacker mint valid tokens for any user, indefinitely, and you will not see it in a log anywhere.
Verification belongs in your code or a CLI where the key already lives. Decoding — which is what you almost always actually want when debugging — needs no key at all.
A JWT is signed, not encrypted
This is the single most common misunderstanding. The three parts of a token are header.payload.signature, and the first two are plain base64url. Anyone holding the token can read every claim in it without any key whatsoever.
So: never put anything secret in a payload. Not an internal user note, not a permissions matrix you would rather not publish, not a phone number. If the contents genuinely need to be hidden, you want JWE, which is encrypted, has five parts, and cannot be decoded here or anywhere else without the key.
Reading the time claims
exp— the token must be rejected on or after this instant. Seconds since the Unix epoch, not milliseconds; a token that appears to expire in 1970 usually means someone passed milliseconds.nbf— “not before”. Rejected until this time. A token that mysteriously fails right after issue is often a clock-skew problem between the issuing and verifying machines.iat— issued at. Useful for spotting a token that was minted far earlier than you expected, i.e. a cached one.
Things worth checking when auth is failing
- Is it actually expired? The badge above tells you against your own clock. If your server disagrees, you have clock skew.
- Does
audmatch? A token minted for one API and presented to another is rejected by any correct verifier, and the error is rarely clear about it. - Is
issthe issuer you configured? Staging and production issuers differ by one subdomain and the failure looks identical to a bad signature. - Is
algwhat you expect? If it saysnone, or RS256 where you configured HS256, stop and look at your verification code — it should pin the algorithm rather than trusting the header.
Frequently asked
Is it safe to paste a JWT into an online decoder?
Only if the decoding happens in your browser. A JWT is a bearer credential: anyone holding it can act as you until it expires. A decoder that posts the token to a server has just been handed your session. This one does all the work client-side — you can confirm it by opening devtools, switching to the Network tab, and watching that pasting a token produces no requests. Even so, treat any production token you paste anywhere as worth rotating.
Why is there no box for the signing secret?
Because encouraging people to paste signing secrets into web pages is a genuinely bad habit, and a secret is far more damaging to leak than a single token — it lets an attacker mint tokens for anyone, forever. Verification belongs in your code or a CLI, not a website. Decoding needs no secret at all, and decoding is what you actually need 95% of the time.
What is the difference between decoding and verifying a JWT?
Decoding just base64url-decodes the header and payload — anyone can do it, because a JWT is signed, not encrypted. Verifying recomputes the signature with the key to prove the token has not been tampered with. Never trust a decoded claim for an authorisation decision without verifying first; the payload is attacker-controlled until the signature checks out.
Is JWT data encrypted?
No. A standard JWT (a JWS) is signed but fully readable by anyone who has it — base64url is encoding, not encryption. Never put anything secret in a payload. If you need the contents hidden, you want JWE, which has five parts instead of three and cannot be decoded without the key.
My token says alg: none. What does that mean?
It means the token is unsigned and anyone can forge one. The 'none' algorithm exists in the spec but accepting it is a classic authentication bypass — a library that honours alg:none will happily validate a token an attacker wrote by hand. Your verification code should pin an expected algorithm rather than trusting the header.
Built by Himanshu Srivastava, a backend engineer in Bengaluru. More in the tools collection.