Glossary
What is a JWT (JSON Web Token)? How the signed pass works and how to use it safely
A JWT (JSON Web Token) is a tamper-proof 'pass' a server signs. How header/payload/signature work, and the dangers: skipping signature verification, allowing alg:none, and putting secrets in the payload.
"The signed pass a server hands you after login" — that's a JWT. Here's how it works and the key points for using it safely (no attack steps).
How it works (three parts)
A JWT is header.payload.signature joined with .. The header and payload are just base64url-encoded (not encrypted); only the signature is made with a secret (or shared) key.
1. header
meta like the signing algorithm. anyone can read it
2. payload
claims like user id and expiry. anyone can read = no secrets
3. signature
made with a key. guarantees no tampering
The key point is that the contents are "just readable." So the payload is not a place for passwords or personal data. A JWT's value is that by verifying the signature, the server can confirm "I issued this token and it hasn't been altered."
Defenses for using it safely
Always verify the signature, and pin the alg (most important)
Verify the signature server-side every time. Pin the accepted signature algorithm (alg) to the value you expect, and reject alg:none (no signature). Don't trust the alg written in the token's header blindly.
Put no secrets in the payload
Assume anyone can decode the contents. Keep secrets — passwords, personal data, API keys — out of it. Include only claims that aren't catastrophic if seen, like identifiers and permissions.
Keep expiry short, and have a way to revoke
Make access tokens short-lived. An over-long expiry stretches the damage window if one is stolen. If you need revocation, pair a short-lived access token with a server-managed refresh/session.
Use a strong key and store it where it can't be stolen
Make the signing key strong, don't reuse it, and store it somewhere safe server-side. Protect the token itself too — keep it from being stolen via XSS, carry it in a cookie with safe attributes (→ beware theft via XSS).
This site's view: a JWT is not an all-purpose session
JWTs are often used to "hold login state," but they have a weakness: revocation is hard. If the signature is valid and unexpired, the server basically trusts it, so making a logout or invalidation take effect immediately is awkward. Our stance is: don't make a JWT a long-lived all-purpose session. Combine a short-lived access token with a server-side, revocable refresh/session, and you get both the JWT's upside (cheap verification) and easy revocation. Pick the right use for it.
Blind spot: "it decoded" is not "it's valid"
Because the contents are readable, anyone can paste a JWT into a JWT decoder and inspect the header and payload. But decoding (reading the contents) and verifying (confirming authenticity) are entirely different. Being able to decode guarantees nothing about validity. What decides whether a token is genuine is always the server-side signature verification. Reading contents for debugging is handy — just don't mistake "I could read it" for "it's valid."
Read next
- Tool: JWT decoder / inspector (check contents, spot alg:none or expiry)
- Glossary: what XSS is (a classic token-theft route) / what CSRF is
- Learn: choosing MFA the right way
FAQ
QIs the content of a JWT encrypted?
No. A standard JWT's header and payload are 'encoded' with base64url, not encrypted, so anyone holding the token can read the contents. So never put secrets like passwords or personal data in the payload. What a JWT protects is not 'confidentiality of contents' but 'that it hasn't been tampered with' (integrity, via the signature).
QWhat's the most dangerous JWT setting?
Not verifying the signature, or accepting 'alg:none' (no signature). Allowing that lets an attacker pass a forged token with freely rewritten contents. The defense is to always verify the signature server-side and pin the accepted signature algorithm (alg) to the value you expect.
QAre decoding and verifying the same thing?
No. Decoding just reads the contents and anyone can do it (you can check with a JWT decoder). Verifying is the server confirming, with a secret/public key, that the signature is valid, the token is unexpired, and the issuer/audience are correct. 'It decoded' does not mean 'it's a valid token' — server-side verification decides authenticity.