What a JSON Web Token actually is
A JSON Web Token carries a set of claims — statements such as who a user is, what they may do, and when the statement stops being true. What you paste above is a JWS: three base64url segments joined by dots, the first two plain JSON and the third a signature over them.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 → {"alg":"HS256","typ":"JWT"} — no key, no permission, one line of code
That is the split which explains most of what people find surprising. Reading a token requires nothing, so never put in a payload what you would not print in a log; trusting one requires the key, and the algorithm you check with has to be one you chose rather than the one the header asks for. Decoding, signing and verification all run in this tab through Web Crypto, and the page has no way to put a token in its own URL.
The three parts
Each part is base64url with its padding stripped, so a token survives being pasted into a URL, a header, or a cookie without further escaping.
| Segment | Holds | Covered by the signature |
|---|---|---|
| Header | How the token was signed: alg, typ, and often a kid naming the key. | Yes — altering it invalidates the signature. |
| Payload | The claims themselves: registered ones such as sub and exp, plus anything the issuer adds. | Yes — altering it invalidates the signature. |
| Signature | The MAC or signature over the first two parts, joined by a dot. | It is the signature. |
base64url is an encoding, not a cipher. Decoding a payload takes no key and no permission — which is why the same claim data must never include anything you would not print in a log.
The registered claims
RFC 7519 reserves seven claim names. None is mandatory, but a token that omits exp has no way to stop being valid, and one that omits iss and aud is hard to scope to a single service.
| Claim | Name | What it carries |
|---|---|---|
| iss | Issuer | Identifies who minted the token, so a verifier can pick the right key and reject tokens from anyone else. |
| sub | Subject | Identifies the principal the claims are about — usually a user id, and unique within the issuer. |
| aud | Audience | Names the recipients the token is for. A service that finds itself absent from aud must reject the token. |
| exp | Expiration time | Seconds since the Unix epoch after which the token must be rejected. The single most important claim to include. |
| nbf |
Signing algorithms
The alg header names one entry from the JOSE registry. The families differ in what the verifier needs to hold: a copy of the signing secret, or only a public key.
| Family | Algorithms | Key | Reach for it when |
|---|---|---|---|
| HMAC | HS256 · HS384 · HS512 | One shared secret, used to sign and to verify. | The same service issues and checks the token, so there is no third party to keep a secret from. |
| RSA PKCS#1 v1.5 | RS256 · RS384 · RS512 | Private key to sign, public key to verify. | Verifiers are separate services, or outside your control, and you need the widest possible library support. |
| RSA-PSS | PS256 · PS384 · PS512 | Private key to sign, public key to verify. | You want the modern RSA padding and control both ends well enough to know PS is supported. |
| ECDSA | ES256 · ES384 · ES512 | Private key to sign, public key to verify. |
How verification actually works
Verifying recomputes the signature over the first two segments, exactly as they appear in the token, and compares it with the third. This is why the tool signs a compacted copy of your payload rather than the indented text in the editor: the bytes that were signed are the bytes that must be checked.
The order matters. Check the structure, then the signature, then the claims. A token whose exp has passed is worth rejecting, but only after you know the exp you are reading is one the issuer actually wrote.
The rule worth carrying away: never verify with the algorithm the token asks for. Pass your verifier an explicit list of algorithms you accept. A verifier that reads alg from the header can be handed an RS256 token rewritten as HS256, signed with the very public key it publishes — the public key becomes the HMAC secret, and the forgery verifies.
That is why the decoder above shows an expected-algorithm control instead of silently following the header. It starts from what the token declares, then checks against your choice, and says so plainly when the two disagree.
Every control on this page
The workbench has two directions and a small set of controls shared between them.
| Control | What it does | Reach for it when |
|---|---|---|
| Decoder / Encoder | Switches between reading a token and signing one. | You have a token to inspect, or claims you want to turn into one. |
| Example | Signs a sample token, minting a throwaway key pair for the asymmetric families. | You want to try RS, PS, ES or EdDSA without having a key pair to hand. |
| JSON / Claims | Swaps the decoded panels between raw JSON and a table that names each claim and dates the time claims. | You want the exact bytes, or you want to know what exp is actually saying. |
| Expected algorithm | Fixes the one algorithm the signature is checked against, and swaps the key box to match. |
What goes wrong in practice
Encoded is not encrypted. Every claim in a JWT is readable by anyone who holds the token, including the user it was issued to. Email addresses, internal ids and role names all leak by design; passwords and API keys in a payload are a live incident, not a code-review nit.
Signatures do not expire on their own. A token stays valid until its exp passes, and there is no way to call it back before then. Anything you might need to withdraw quickly — a session, an elevated role — needs either a short life or a revocation list the verifier actually checks.
The algorithm is an attacker-controlled field until you pin it. Accept an explicit allowlist in your verifier and treat everything else, none included, as a rejected token.
Header parameters that name a key are equally attacker-controlled. jku, jwk and x5u ask a verifier to fetch or trust key material chosen by the token; unless you are certain your library ignores them, assume a token carrying them is trying something.
Where the token lives matters as much as what is in it. localStorage is readable by any script on the page, which turns one cross-site scripting bug into stolen credentials. Prefer a cookie with HttpOnly, Secure and SameSite set, and keep the lifetime short.
Frequently asked questions
Web Crypto API. There is no request to any server, which is also why the tool works with the network switched off. The page has no way to put a token in its URL either, so nothing lands in browser history or server logs.base64url, an encoding anyone can reverse in one line of code. If the contents must stay private, you want a JWE, the five-part encrypted format, which this tool identifies but cannot open.