JWT Decoder guide
How JSON Web Tokens are built, what the XGM JWT Decoder shows about claims and expiry, how signature verification works and which mistakes to avoid.
How a JWT is built
A JSON Web Token (RFC 7519) is a compact way to pass claims, such as a user ID and an expiry time, between systems. It consists of three parts separated by dots: a header that names the signing algorithm, a payload with the claims, and a signature over the first two parts. Each part is base64url-encoded.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 header: {"alg":"HS256","typ":"JWT"}
.eyJzdWIiOiIxMjMiLCJleHAiOjE3NTc5MDAwMDB9 payload: {"sub":"123","exp":1757900000}
.3q2-7wrBx... signature: HMAC-SHA256 over header.payloadAnyone can decode the header and payload; base64url is an encoding, not encryption. The signature is what makes the token trustworthy: only a party with the right key can produce it, and any change to the header or payload breaks it. Encrypted tokens also exist (JWE), but most tokens in APIs and login systems are signed only.
How to use the JWT Decoder
- Open the JWT Decoder and paste a token. It is decoded in your browser as you type.
- Read the header and payload as formatted JSON, and the notes about algorithm, expiry and claims.
- To verify the signature, enter the HMAC secret (tick base64url if the secret is encoded that way) or paste a public key in PEM or JWK format.
- Press Verify signature and read the result.
Treat real tokens as passwords
Registered claims
| Claim | Name | Meaning |
|---|---|---|
iss | Issuer | Who created and signed the token |
sub | Subject | Who or what the token is about, often a user ID |
aud | Audience | Who the token is intended for; recipients must check it |
exp | Expiration time | Seconds since 1970-01-01 UTC after which the token must be rejected |
nbf | Not before | Time before which the token must be rejected |
iat | Issued at | When the token was created |
jti | JWT ID | Unique identifier, useful for revocation lists and replay protection |
{
"iss": "https://auth.example.com",
"sub": "user-8812",
"aud": "https://api.example.com",
"iat": 1789462800,
"exp": 1789463700,
"scope": "orders:read"
}Time claims are Unix timestamps in seconds, not milliseconds. The decoder converts them into readable durations, such as "expired 3 hours ago" or "valid for another 14 minutes", using your device's clock. If the device clock is wrong, those durations are wrong too.
What the decoder warns about
| Note | Severity | Why |
|---|---|---|
| alg is "none" | Critical | The token is unsigned; accepting it lets anyone forge claims |
| The header has no alg | Critical | Libraries should reject tokens without an algorithm |
| The signature part is empty | Critical | A signed algorithm with no signature cannot be valid |
| Expired … ago (exp) | Warning | Servers must reject the token |
| No exp claim | Warning | The token never expires unless the server enforces a lifetime |
| Not valid yet (nbf) | Warning | The token is used before its start time, or clocks differ |
| iat is in the future | Warning | The issuer's clock is probably wrong |
| Payload contains password/secret-like fields | Warning | The payload is readable by anyone who has the token |
Verifying signatures
| alg | Type | Key needed to verify |
|---|---|---|
HS256, HS384, HS512 | HMAC with SHA-2 | The shared secret |
RS256, RS384, RS512 | RSA PKCS#1 v1.5 | RSA public key (PEM or JWK) |
PS256, PS384, PS512 | RSA-PSS | RSA public key (PEM or JWK) |
ES256, ES384, ES512 | ECDSA | EC public key on the matching curve (PEM or JWK) |
With HMAC algorithms, the same secret signs and verifies, so everyone who can verify can also create tokens. Asymmetric algorithms separate the two: the issuer keeps the private key and publishes the public key, often as a JWKS document, so any service can verify without being able to issue. For systems where many services consume tokens, asymmetric keys are the safer design.
Verification uses the browser's WebCrypto implementation. A successful verification proves the token was signed with the matching key; it does not check iss, aud or whether the token has been revoked, which remain the job of the receiving server.
Common JWT mistakes
- Accepting the algorithm from the token. Configure the expected algorithms on the server; never let the
algheader choose, which is hownoneand key-confusion attacks work. - Weak HMAC secrets. Short or guessable secrets can be brute-forced offline from a single token. Use at least as many random bytes as the hash output, for example 32 bytes for HS256.
- No expiry, or very long lifetimes. Tokens cannot easily be revoked, so keep access tokens short-lived and use refresh tokens for long sessions.
- Sensitive data in the payload. Anything in the payload is readable by whoever holds the token, including browser extensions and logs.
- Not checking aud. A token issued for one service should not be accepted by another that happens to trust the same issuer.
- Storing tokens where scripts can read them. Tokens in
localStorageare exposed to any XSS; HttpOnly cookies avoid that for browser sessions.
The CSP guide covers limiting script injection, which protects tokens stored in the browser. For inspecting the JSON inside tokens in more detail, the JSON Formatter can pretty-print decoded payloads.
FAQ
Is it safe to paste a token here?
The token and keys are processed only in your browser and are not uploaded or put in the URL. A live token still grants access, so prefer expired or test tokens.
Can the decoder read an encrypted JWT?
No. Encrypted tokens (JWE) have five parts and need the decryption key. The decoder handles signed tokens (JWS) with three parts.
Why does verification fail with the right secret?
Check whether the secret is stored as base64url (tick the option), whether the token was changed, and whether the algorithm in the header matches the key type.
What does alg none mean?
The token has no signature. Servers must never accept unsigned tokens for authentication; the decoder marks them as critical.
Why is my token expired when it was just issued?
Your device clock or the issuer's clock is wrong, or exp was set in milliseconds instead of seconds. Compare with iat.
Can I decode a token without the key?
Yes. Header and payload are only base64url-encoded. The key is needed to verify that the token is genuine.
What is a JWKS?
A JSON Web Key Set, a JSON document with one or more public keys, usually published by an identity provider. Paste the whole document into the decoder's key box: the key whose kid matches the token header is picked for you, and a kid that is not in the set is reported instead of being silently replaced by the first key.
Should I use HS256 or RS256?
HS256 is fine when one service both issues and verifies tokens. RS256 or ES256 are better when several services verify tokens, because they only need the public key.
Can a JWT be revoked?
Not by itself. Use short lifetimes, and keep a denylist of jti values or session state on the server when immediate revocation is required.