Decode a JSON Web Token's header and payload, read its claims as dates rather than epoch seconds, and verify an HMAC signature locally with a shared secret. Policy problems — no issuer, no audience, an expiry before the issue time, a lifetime measured in days — are flagged rather than left for you to spot.
Segments in every token
3
Verifiable here
HS256/384/512
Encoding, unpadded
base64url
Tokens uploaded
0
Step by step
How to use it
01Paste the token
All three segments decode immediately — header, payload, and the signature left as-is. Nothing is transmitted, which is the only acceptable arrangement for a credential.
02Read the claims as dates
iat, nbf, and exp are epoch seconds and unreadable at a glance. They are rendered as real timestamps, so an expiry that has already passed is obvious rather than arithmetic.
03Check the policy flags
A missing issuer or audience, no expiry at all, an expiry before the issue time, or a lifetime over 24 hours are each called out. These are the findings that turn up in security reviews.
04Verify the signature, if it is HMAC
Paste the shared secret and the HS256, HS384, or HS512 signature is checked in your browser. RS and ES tokens are signed with a private key and cannot be verified from a secret at all.
Worked example
What is actually in a token
Three base64url segments joined by dots. Two of them are readable by anyone who has the token, which is the fact that most misuse of JWTs comes down to.
Given
Format
header.payload.signature
Encoding
base64url, unpadded
Encryption
none
The three segments and who can read them
header {"alg":"HS256","typ":"JWT"}
anyone with the token
payload {"sub":"1234","exp":1735689600,
"role":"admin"}
anyone with the token
signature HMAC-SHA256(header.payload, secret)
proves nobody altered the first two
it does NOT hide them
Readable by anyone
header + payload
Signature proves
integrity
Signature hides
nothing
A signed JWT is tamper-evident, not confidential: base64url is an encoding and the payload is plain text to anyone holding the token — including the browser it was issued to. Putting an email, an internal user id, or a role hierarchy in there discloses all of it. If the contents must stay secret you need an encrypted token or an opaque one, not a signed one.
Before you trust a token
What to know about JWTs
Decoding is not verifying
Anyone can read a token's payload and anyone can craft one with whatever claims they like. Only checking the signature against a key you trust makes the contents meaningful. A backend that decodes without verifying is a backend that accepts any role its attacker types.
Never trust the alg header
The token tells you which algorithm it claims to use, and taking that at face value is the source of two classic vulnerabilities: alg: none, and an RS256 verifier tricked into treating a public key as an HMAC secret. Pin the expected algorithm server-side and reject anything else.
You cannot revoke a stateless token
Once issued, a JWT is valid until it expires — logging out, deleting the session, or banning the user changes nothing the verifier can see. That is why access tokens should have short lifetimes and why a denylist or a refresh-token exchange is needed for real revocation.
Expiry claims are seconds, and clocks drift
exp, iat, and nbf are epoch seconds, not milliseconds — a token with an exp in milliseconds is valid for about fifty thousand years. Verifiers also allow a small clock skew, so a token can be accepted a few seconds past its stated expiry.
Size travels with every request
A JWT rides in a header on every call, so a payload stuffed with permissions and profile data adds a kilobyte to every request and can hit proxy header limits. Keep claims to identifiers and look the rest up.
This decoder never sees your token
Decoding and HMAC verification both run in your browser using the Web Crypto API. That matters more here than anywhere: pasting a live token into a server-side decoder hands someone a working credential.
The judgement call
Should this be a JWT at all?
JWTs solve one problem well and are routinely used for several they solve badly.
Stateless auth between your own services
Good fit
The verifier needs only a key, not a database lookup. This is the case the format was designed for.
A short-lived access token
Good fit
Minutes, not days. Short lifetimes are what make the absence of revocation tolerable.
A long-lived session in a browser
Use a session cookie
Server-side sessions revoke instantly, stay small, and avoid storing a bearer token in JavaScript-reachable storage.
Carrying anything confidential
Not signed JWT
The payload is plain text to anyone with the token. Encrypt it, or use an opaque token and look the data up.
Permissions that change during a session
Look them up
Claims are frozen at issue time. A revoked admin keeps their admin claim until the token expires.
A token you need to invalidate on logout
Needs state
Statelessness is the trade. Real revocation means a denylist or short access tokens plus refresh exchange.
Reference
How a token is put together
Structure
header.payload.signatureThree base64url segments joined by dots. The first two are data; the third authenticates them.
Encoding
base64url, no paddingUses - and _ instead of + and / and drops the = padding, so standard Base64 decoding fails on it.
HMAC algorithms
HS256 · HS384 · HS512Shared-secret signatures, the only family verifiable from a secret — and the only ones this tool can check.
Asymmetric algorithms
RS · PS · ES familiesSigned with a private key and verified with a public one. A secret cannot verify them.
Time claims
exp · iat · nbfEpoch seconds. Milliseconds are a common bug and produce absurdly long-lived tokens.
Identity claims
iss · aud · subIssuer, audience, and subject. Verifying iss and aud is what stops a token issued for another service being replayed at yours.
FAQ
Questions, answered plainly
How do I decode a JWT?
Paste it in — the header and payload are base64url and decode immediately, with the time claims rendered as real dates. It happens entirely in your browser, which is the only safe way to inspect a live token.
Is a JWT encrypted?
No. A signed JWT is encoded, not encrypted: anyone holding the token can read the header and payload in full. The signature proves the contents have not been altered — it does not conceal them. Anything confidential belongs outside the token.
Can I verify a token here?
If it uses HMAC — HS256, HS384, or HS512 — paste the shared secret and the signature is checked locally with the Web Crypto API. RS, PS, and ES tokens are signed with a private key and cannot be verified from a secret, so those are decoded but not verified.
What is the alg: none attack?
A forged token that sets its algorithm header to none and omits the signature. A verifier that trusts the header and skips verification accepts it, along with whatever claims the attacker wrote. The defence is to pin the expected algorithm on the server and reject anything else — never read it from the token.
How do I revoke a JWT?
You cannot, without adding state. A signed token stays valid until it expires, which is the trade you accept for stateless verification. In practice: keep access tokens short-lived, use refresh tokens for renewal, and maintain a denylist if you need immediate revocation.
Is my token sent anywhere?
No. Decoding and HMAC verification both run in your browser. This matters more than for any other tool here — pasting a live token into a server-side decoder hands whoever runs it a working credential.
Decoding and HMAC verification both run in your browser via the Web Crypto API. No token or secret is ever transmitted.