What Is a JWT? JSON Web Tokens Explained Simply

Published 2026-05-13

JSON Web Tokens — JWTs, usually pronounced "jots" — are the most common way modern web applications prove who you are after you log in. If you have ever inspected the network traffic of a web app and seen a long string in three dot-separated parts, that was almost certainly a JWT. Here is what they are and how they work, without the jargon.

The problem JWTs solve

HTTP is stateless: each request arrives with no memory of the previous one. So after you log in, how does the server know it is still you on the next request? The traditional answer was server-side sessions: the server stores your session in memory or a database and gives you a cookie with a session ID. That works, but it means the server has to look up and store state for every logged-in user.

JWTs flip this around. Instead of the server remembering you, it gives you a signed token that contains your identity. On each request you send the token back, and the server simply verifies the signature. No lookup, no shared session store — which is why JWTs scale so well across multiple servers.

The three parts of a JWT

A JWT is three Base64Url-encoded pieces joined by dots: header.payload.signature.

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiQWxpY2UifQ.SflKxw...
        header                    payload                signature
  • Header — says what type of token it is and which signing algorithm was used (for example HS256).
  • Payload — the "claims": the actual data, such as the user ID (sub), name, roles, and an expiry time (exp).
  • Signature — a cryptographic seal over the header and payload, created with a secret key only the server knows.

The most important thing to understand

A JWT is signed, not encrypted. The payload is merely Base64-encoded, which is trivially reversible — anyone who has the token can read its contents. Paste any JWT into a decoder and the claims appear in plain text, no key required.

So what does the signature protect? Tampering. If an attacker changes the payload — say, flipping "role": "user" to "role": "admin" — the signature no longer matches, and the server rejects the token. The signature proves the token was issued by your server and has not been altered; it does not hide the contents.

What you should and should not put in a JWT

Because the payload is readable by anyone holding the token, treat it as public:

  • Good to include: a user ID, roles or permissions, the token's expiry. Just enough to identify the session.
  • Never include: passwords, credit card numbers, personal data, or any secret. If the token leaks into a log, a URL, or browser history, everything in it is exposed.

Expiry and security tips

  1. Always set an expiry (exp). A token that never expires is a permanent key if stolen. Short lifetimes (minutes to hours) limit the damage.
  2. Use refresh tokens for long sessions: a short-lived access token plus a longer-lived refresh token that can be revoked.
  3. Store them carefully in the browser. localStorage is vulnerable to cross-site scripting; HttpOnly cookies are safer against that particular attack.
  4. Most "login bugs" are expiry bugs. When debugging a 401, decode the token and check the exp claim first — it is usually expired or the server clock is off.

To see what is inside a token, paste it into the decoder below. It splits the JWT and shows the header and payload — including human-readable dates for the issued-at and expiry claims — entirely in your browser, so the token is never sent anywhere.

Related tool: JWT Decoder — Decode and inspect JSON Web Tokens securely in your browser.
Copied!