The first time I really looked at a JWT, I was staring at a login bug at 11 PM, copying a long, dot-riddled string out of a browser’s dev tools and wondering what on earth it said. If you’ve seen a value shaped like xxxxx.yyyyy.zzzzz in a cookie or an Authorization header and felt the same way, this is the explanation I wish I’d had that night.
What a JWT is for
A JWT is a compact, self-contained way to carry claims: pieces of information such as “this is user #4521” or “this token expires at 3 PM.” When you log in, the server hands you a token; your browser sends it back with each request, and the server can trust it without looking anything up in a database. That statelessness is what makes JWTs so popular for APIs.
The three parts of a token
Every JWT has three sections separated by dots. Each is Base64URL-encoded (not encrypted; more on that below):
- Header. Says what type of token it is and which signing algorithm was used (for example,
HS256orRS256). - Payload. The actual claims: user ID, roles, issued-at time, and expiry. These are readable by anyone who has the token.
- Signature. A cryptographic stamp created from the header, payload, and a secret key. It lets the server verify the token hasn’t been tampered with.
The most important thing to understand: it’s signed, not secret
This trips up almost every beginner. The payload of a JWT is encoded, not encrypted. Anyone who intercepts the token can read its contents: the user ID, roles, and any other claims are all visible.
What the signature guarantees is integrity: nobody can change the payload without the secret key, because doing so would break the signature. So the rule is simple: never put sensitive data (passwords, card numbers, secrets) inside a JWT payload. Treat it as public information that merely can’t be forged.
How verification works
When the server receives a token, it recomputes the signature from the header and payload using its secret key, then compares it to the signature in the token. If they match, the token is authentic and untampered. If they don’t, it’s rejected. The server also checks the expiry claim so old tokens stop working automatically.
Inspecting a token safely
When debugging authentication, you often need to peek inside a token to check its claims or expiry. You can decode the header and payload with our JWT decoder: paste the token and it splits and decodes the parts for you, right in your browser.
Two safety notes when decoding tokens:
- Use tools that decode locally. Because a token can be used to impersonate you until it expires, never paste a live production token into a random site that sends it to a server. A browser-based decoder that keeps the token on your device is far safer.
- Decoding is not verifying. A decoder shows you what’s inside, but only the server with the secret key can prove a token is genuine.
If you’re curious about the encoding underneath, each section is Base64URL, the same family covered in our guide to Base64 encoding.
Common beginner mistakes
- Storing secrets in the payload: remember, it’s readable by anyone.
- Never setting an expiry: a token that lives forever is a security hole if it leaks.
- Trusting a token without verifying the signature: always verify server-side.
- Using a weak signing secret: a short, guessable secret undermines the whole system.
Questions developers actually ask
Is the data in a JWT encrypted?
No. The header and payload are only encoded and can be read by anyone. The signature prevents tampering, not reading.
Can a JWT be tampered with?
Not without being detected. Changing any part invalidates the signature, so the server will reject it, provided the server actually verifies the signature.
Where should I store a JWT in the browser?
It’s a trade-off. HttpOnly cookies protect against cross-site scripting but need CSRF protection; local storage is simpler but exposed to scripts. Choose based on your app’s threat model.
What does an expired token do?
A well-built server checks the expiry claim and rejects tokens past their time, forcing a fresh login or token refresh.
If you remember three things
Keep secrets out of the payload, always set an expiry, and always verify the signature on the server. A JWT is just a signed note that says who you are and when it stops being valid, nothing more mysterious than that. Next time one lands you in a late-night debugging session, drop it into the JWT decoder and read exactly what it’s telling you.
Handy tools for this topic
70+ free tools, zero sign-up
Every ToolBrainy tool runs right in your browser — no accounts, no watermarks and no limits. Compress a PDF, generate a strong password, convert an image and plenty more.



