JWT Decoder & Inspector
Signature verification requires the secret key and is not performed client-side.
What is a JWT?
JWT (JSON Web Token) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. A JWT consists of three base64url-encoded parts separated by dots: a header that specifies the algorithm used, a payload that contains claims (statements about an entity), and a signature used to verify the token's integrity. JWTs are widely used for authentication and authorization in web applications and APIs.
How JWT Decoding Works
The header and payload of a JWT are simply base64url-encoded JSON — no secret key is needed to decode them. Anyone who has the token can read its contents, which is why sensitive data should never be stored in a JWT payload without additional encryption. The signature, however, requires the original secret key (or private key for asymmetric algorithms) to verify. This tool decodes only — it does not verify signatures.
Common JWT Claims
| Claim | Full Name | Description |
|---|---|---|
| sub | Subject | Identifies the principal (user) the token refers to |
| iss | Issuer | Identifies who issued the token |
| aud | Audience | Identifies the recipients the token is intended for |
| exp | Expiration Time | Unix timestamp after which the token must not be accepted |
| iat | Issued At | Unix timestamp when the token was issued |
| nbf | Not Before | Unix timestamp before which the token must not be accepted |
| jti | JWT ID | Unique identifier for the token to prevent replay attacks |
The Anatomy of a JWT
A JWT is three base64url strings joined by dots — header.payload.signature. Split on the dots and you can read the first two parts with nothing more than a base64 decoder.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 ← header
.eyJzdWIiOiIxMjM0NSIsIm5hbWUiOiJBbGV4In0 ← payload
.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk ← signature
Note the encoding is base64url, not standard base64: + and / are replaced by - and _, and the = padding is stripped so the token is safe in URLs and headers. That is why pasting a JWT segment into a generic base64 decoder sometimes fails.
Signing Algorithms
The alg field in the header names the algorithm used to produce the signature. The practical split is symmetric versus asymmetric.
| Algorithm | Type | Key | When to use it |
|---|---|---|---|
| HS256 / HS384 / HS512 | Symmetric (HMAC) | One shared secret signs and verifies | A single service issues and verifies its own tokens |
| RS256 / RS384 / RS512 | Asymmetric (RSA) | Private key signs, public key verifies | Many services verify tokens from one issuer — the standard for OIDC |
| ES256 / ES384 | Asymmetric (ECDSA) | Private key signs, public key verifies | Same as RS256 with much smaller signatures |
| none | — | No signature at all | Never. See below. |
alg: none attack. The spec permits an algorithm of none, meaning unsigned. A naive verifier that trusts the header will accept a token an attacker forged with arbitrary claims. The related algorithm confusion attack changes RS256 to HS256 and signs with the public key as the HMAC secret. The defence for both is the same: your server must decide which algorithm is acceptable and refuse everything else — never read alg from the token to choose how to verify it.
Decoding Is Not Verifying
This tool decodes. It reads the header and payload and shows you what is inside. It does not check the signature, because doing so would require your secret or public key, and no key of yours should ever be pasted into a web page.
That distinction matters in your own code too. Most JWT libraries expose both a decode and a verify function, and reaching for decode in request-handling code is a serious vulnerability — it means any attacker can hand you a token they wrote themselves. Decoding is for debugging and for reading claims from a token you have already verified. Server-side, always call verify.
A complete verification checks all of the following:
- The signature is valid for an algorithm you chose, not one the token names.
expis in the future andnbfis in the past, allowing a small clock skew of about 60 seconds.issmatches the issuer you expect.audcontains your service — a valid token minted for a different audience must be rejected.
The time-based claims are Unix timestamps in seconds. When a token is rejected as expired and you want to know precisely when it lapsed, our Unix timestamp converter turns the raw exp value into a readable date.
Common Causes of "Invalid Token"
- Clock skew. If the issuing and verifying machines disagree by more than a few seconds, a freshly minted token can fail its
nbfcheck. Run NTP and allow a small leeway. - The
Bearerprefix was not stripped. TheAuthorizationheader isBearer <token>. Passing the whole header value to the parser yields a malformed token. - Whitespace from copy and paste. A trailing newline or a line break introduced by a terminal changes the signature input and invalidates it.
- Key rotation. The issuer rotated its signing key and your cached JWKS is stale. Refresh the key set when you encounter an unknown
kid. - Wrong encoding of the secret. HMAC secrets are bytes. If one side treats a base64 secret as raw text and the other decodes it first, signatures will never match.
Practical Guidance
Keep access tokens short-lived — 5 to 15 minutes is typical — and pair them with a longer-lived refresh token. The reason is that JWTs are self-contained: a verifier accepts one without consulting any database, which is what makes them fast and also what makes them impossible to revoke. Until a stolen token expires, it works. A short exp is the main thing limiting that window.
Where you store the token matters as much as how you sign it. localStorage is readable by any JavaScript on the page, so a single XSS flaw exfiltrates the session. An HttpOnly, Secure, SameSite=Strict cookie is unreachable from JavaScript and is the better default for browser applications.
Finally, keep payloads small. Every request carries the token in a header, and some proxies reject headers beyond 8 KB. Store an identifier and look up the rest server-side rather than embedding a full user profile.
Frequently Asked Questions
jti values checked on each request (which reintroduces a database lookup), or bumping a per-user token version claim.kid header?kid tells the verifier which one to use — which is what makes seamless key rotation possible.