What Is a JWT? JSON Web Tokens Explained (Decode & Verify)
If you have built or used a modern web API, you have almost certainly met the JWT β the JSON Web Token. It is the string that proves "this request really is from a logged-in user" without the server having to remember every session. This guide explains what a JWT is, how its three parts fit together, how signing and verification work, and the mistakes to avoid when you use them.
What is a JWT?
A JSON Web Token is a compact, URL-safe way to represent claims β pieces of information β that can be passed between two parties and verified. In plain terms, it is a signed packet of JSON that says things like "this is user 42, they are an admin, and this token is valid until 3pm." Because it is signed, the receiver can trust that the contents have not been changed, even though anyone can read them.
JWTs are most often used for authentication: after you log in, the server hands you a token, and your browser or app sends it with every following request. The server checks the signature and lets you in β no database lookup required.
The three parts of a JWT
A JWT is three Base64URL-encoded sections joined by dots: header.payload.signature. If you paste one into the PAYATE JWT Decoder, you will see each part laid out.
- Header β a small JSON object that says which signing algorithm is used (for example
HS256orRS256) and that the type isJWT. - Payload β the claims: the actual data, such as the user ID, roles and expiry time.
- Signature β a cryptographic signature over the header and payload, created with a secret or private key. This is what makes the token tamper-evident.
Understanding the payload and claims
The payload holds "claims," and some names are standardised so every library understands them: sub (the subject, usually the user ID), iat ("issued at," a Unix timestamp), exp (expiry, after which the token must be rejected), and iss / aud (who issued the token and who it is for).
Timestamps are Unix epoch seconds, so exp might look like 1793664000. If you ever need to turn one of those numbers into a readable date, the Epoch & Timestamp Converter does it instantly. You can add your own custom claims too, such as role or plan.
How signing and verification work
This is the part that confuses people, so let's be precise. A JWT is signed, not encrypted. The payload is only Base64-encoded, which is reversible β anyone who has the token can read its contents. What they cannot do is change it without breaking the signature.
There are two common families of algorithms. HMAC (HS256/384/512) uses a single shared secret to both sign and verify; it is simple and fast, ideal when one system does both. RSA / ECDSA (RS256, ES256) uses a private key to sign and a matching public key to verify, which suits systems where many services verify but only one issues.
To verify, the receiver recomputes the signature over the received header and payload using the key and compares it to the signature in the token. If they match and the token has not expired, it is trusted. You can watch this in action: build and sign a token with the JWT Generator, then paste it into the JWT Decoder to inspect it.
How JWTs are used for authentication
A typical login flow looks like this: you submit your email and password; the server checks them, then creates a JWT containing your user ID and an expiry, signs it, and returns it; your client stores the token and sends it on every request, usually in an Authorization: Bearer <token> header; and for each request, the server verifies the signature and expiry and reads your identity straight from the token.
Because the server does not need to store the session, this approach scales well across many servers β any of them can verify the token independently. That statelessness is the main reason JWTs are popular for APIs and single-page apps.
JWT security: the mistakes to avoid
- Putting secrets in the payload. Remember the payload is readable by anyone. Never store passwords, card numbers or other sensitive data in it.
- Weak HMAC secrets. If you sign with
HS256, your secret must be long and random β a short password can be brute-forced, letting an attacker forge tokens. Generate a strong one with the Password Generator. - Not checking
exp. A token with no expiry, or one you never check, can be replayed forever. Keep lifetimes short and use refresh tokens for long sessions. - The "alg: none" trap. Older libraries accepted tokens that claimed no signature. Always pin the expected algorithm on the server and reject anything else.
- Storing tokens unsafely. In a browser, a token in
localStorageis exposed to any cross-site scripting. Consider secure, HttpOnly cookies depending on your threat model.
JWT vs session cookies
Traditional sessions store a random ID in a cookie and keep the real data on the server. JWTs put the data in the token itself. Sessions are easy to revoke (just delete them server-side) but need shared storage; JWTs are stateless and scale easily but are harder to revoke before they expire. Many real systems use both: a short-lived JWT for access plus a server-tracked refresh token you can revoke.
Key takeaways
A JWT is a signed, Base64URL-encoded packet of JSON with three parts β header, payload and signature. It lets a server verify a user's identity and claims without storing a session, which is why it powers so many APIs. Just remember it is signed, not encrypted: never put secrets in the payload, always set and check an expiry, and sign with a strong key. To explore tokens hands-on, decode one with the JWT Decoder and create one with the JWT Generator.