What Is a JWT? Structure, Claims & Security Explained
September 26, 2026 · Security
JWT (JSON Web Token) is how modern apps pass identity around: after you log in, the server hands you a signed token, and you attach it to every request instead of re-sending your password. This guide explains the three-part structure, what the claims mean, and — most importantly — the security rules that separate a correct implementation from a breach waiting to happen.
What is a JWT, in one paragraph
A JWT is a compact, URL-safe string with three dot-separated parts: header.payload.signature. The header says how it's signed, the payload carries claims (who you are, when it expires), and the signature proves nobody tampered with the first two. Servers verify the signature instead of looking up a session — which is why JWTs scale so well across distributed systems.
The three parts, with a worked example
A real (unsigned-demo) token looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- Header —
{"alg":"HS256","typ":"JWT"}, base64url-encoded. Declares the signing algorithm. - Payload —
{"sub":"1234567890","name":"John Doe","iat":1516239022}, base64url-encoded. The claims. - Signature — HMAC-SHA256 of
header.payloadusing the secret. This is the tamper-evidence seal.
Anyone can read the first two parts (more on that below). Only someone with the secret can produce a valid third part.
See it yourself: paste any token into our free JWT Decoder to inspect its header, payload, claims, and expiry — entirely in your browser.
Common registered claims, explained
| Claim | Name | Meaning |
|---|---|---|
iss | Issuer | Who created the token ("auth.myapp.com") |
sub | Subject | Who the token is about (usually a user ID) |
aud | Audience | Who the token is for — reject tokens meant for someone else |
exp | Expiration | Unix timestamp after which the token is invalid |
iat | Issued at | When the token was created |
nbf | Not before | Token isn't valid before this time |
Treat these as a verification checklist: a robust verifier checks the signature and that iss/aud match expectations and that exp/nbf bracket the current time. Checking only the signature is half the job.
Decoding vs verifying: the crucial difference
This is the misunderstanding behind a whole category of vulnerabilities. Decoding is just base64url-decoding the payload — anyone can do it, no secret needed. Verifying is recomputing the signature with the secret/key and comparing. Code that "validates" a token by decoding it and reading exp has validated nothing — an attacker can mint a token with any claims they like, because the signature check never ran.
Rule: never trust a claim you haven't verified. If your library has separate decode and verify functions, you want verify on every request path.
Signed vs encrypted: JWS and JWE
A standard JWT is a JWS (JSON Web Signature): signed for integrity, but the payload is readable. Base64url is an encoding, not encryption — pasting a token into any decoder reveals everything. If the payload must stay confidential, you need JWE (JSON Web Encryption), which actually encrypts the content. In practice, the simpler rule wins: don't put secrets in JWTs. User IDs, roles, and expiry are fine; passwords, API keys, and personal data are not.
JWT vs sessions: when each fits
- JWTs fit distributed systems and APIs: stateless verification, no session store to scale, natural for mobile apps and microservices.
- Sessions fit when you need instant revocation (log out everywhere, ban a user) — a server-side session dies the moment you delete it, while a JWT lives until
expunless you add revocation infrastructure (denylists, short lifetimes).
The honest trade-off: JWTs trade revocation simplicity for scalability. Short-lived access tokens plus revocable refresh tokens are the standard compromise.
Common JWT mistakes to avoid
- Trusting the
algheader blindly — the infamous "alg=none" attack: if your verifier accepts tokens that declare no signature, attackers forge at will. Whitelist expected algorithms. - Weak HS256 secrets — HMAC is only as strong as the secret; "secret123" falls to brute force. Use long random secrets.
- Storing tokens in localStorage without thinking — any XSS vulnerability becomes full account takeover. Weigh httpOnly cookies (see FAQ).
- Putting sensitive data in the payload — it's readable by design.
- Long-lived access tokens — every leak's blast radius is the token's lifetime. Keep them short.
Frequently asked questions
- What does JWT stand for?
- JSON Web Token. It's a compact, URL-safe way to represent claims (pieces of information) between two parties, defined by RFC 7519. Despite the name, the "JSON" part is just the payload format — the security comes from the signature.
- Is a JWT encrypted?
- Not by default. A standard JWT (technically a JWS — JSON Web Signature) is signed but readable by anyone who has it: the payload is only base64url-encoded, which is encoding, not encryption. If the payload contains secrets, you need JWE (JSON Web Encryption) instead — or better, don't put secrets in tokens at all.
- How long should a JWT last?
- As short as practical: 5–15 minutes for access tokens is the common guidance, paired with a longer-lived refresh token (hours to days) that can be revoked. Long-lived access tokens turn every leak into a long-lived breach.
- Can I decode a JWT without the secret?
- Yes — decoding (reading the header and payload) needs no secret, because they're only base64url-encoded. Verifying the signature is what needs the secret (HS256) or public key (RS256). Never confuse "I decoded it" with "I trust it".
- Where should I store JWTs?
- It's a trade-off: localStorage is convenient but readable by any JavaScript (XSS steals it); httpOnly cookies are invisible to JavaScript but need CSRF protection. For most web apps, httpOnly + SameSite cookies with CSRF tokens is the safer default. There is no option with zero trade-offs.
- What's the difference between HS256 and RS256?
- HS256 uses one shared secret for both signing and verifying (HMAC) — simple, but anyone who verifies can also forge. RS256 uses an RSA key pair: the server signs with the private key, anyone verifies with the public key. RS256 fits distributed systems where verifiers shouldn't be able to mint tokens.
- What happens when a JWT expires?
- The `exp` claim tells verifiers to reject it after that Unix timestamp. Your application should then use a refresh token to obtain a new access token — or force re-authentication if the refresh token is expired or revoked too.
Related articles
MD5 vs SHA-1 vs SHA-256 vs SHA-512: Which Hash Algorithm to Use
An honest comparison of common hash algorithms: what each is still good for, why MD5 and SHA-1 are broken for security, and what to use instead.
SecurityPassword Entropy Explained: Bits, Length & Real Security
What password entropy really measures, why length beats complexity, and how to read the bits number like a security engineer.
Web DevelopmentBase64 Encoding Explained: How It Works & When to Use It
What base64 really does, why it inflates data by 33%, base64 vs base64url, and when to reach for it — and when not to.