The Complete JWT Guide
A practical pillar guide to JSON Web Tokens — structure, claims, algorithms, verification, and how to use Cyberway tools safely.
By Mariana Soto · Published 2026-07-01 · Updated 2026-08-22
JSON Web Tokens are everywhere in modern APIs — mobile apps, microservices, single-page applications, and machine-to-machine integrations all rely on them. This guide explains how JWTs work, what can go wrong in production, and how to use the Cyberway JWT Decoder and JWT Generator while you learn. It is written for developers who need to implement or debug authentication, not for security auditors signing off on a compliance review.
When JWTs make sense (and when they do not)
JWTs excel when you need stateless verification: an API can validate a signature and read claims without looking up session state in Redis on every request. They work well for service-to-service calls, short-lived access tokens, and federated identity where an issuer you trust signs claims you consume.
They are a poor default when you need instant revocation for every user session, when tokens carry large payloads, or when a simple HttpOnly session cookie would suffice. Many teams over-adopt JWTs because they sound modern, then struggle with logout, rotation, and token theft. If your primary requirement is "user clicks logout and is immediately signed out everywhere," a server-side session is often simpler.
Anatomy of a JWT
A JWT has three Base64URL-encoded parts separated by dots: header, payload, and signature.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 ← header (JSON)
.
eyJzdWIiOiJ1c2VyLTEyMyIsImV4cCI6... ← payload (JSON claims)
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← signature (binary, Base64URL)
The header usually declares alg (signing algorithm) and typ (token type, typically JWT). The payload carries claims — statements about the subject. The signature binds header and payload to key material so recipients can detect tampering.
Base64URL is not encryption. Anyone who possesses the token can decode the header and payload without a key. That is why JWTs must never hold secrets in the payload unless you also encrypt the token (JWE), which is a separate pattern.
Paste any sample token into the Cyberway decoder to see each part rendered as JSON with inline claim tooltips.
Registered claims you should know
RFC 7519 defines registered claim names. You will see these on nearly every production token:
| Claim | Meaning | Example pitfall |
|-------|---------|-----------------|
| iss | Issuer — who created the token | Accepting tokens from any issuer |
| sub | Subject — who the token is about | Confusing sub with username display |
| aud | Audience — intended recipient(s) | API accepts tokens meant for another service |
| exp | Expiration time (Unix seconds) | Storing exp in milliseconds |
| nbf | Not before — token invalid before this time | Clock skew causing false rejections |
| iat | Issued at | Using iat as a session revocation mechanism |
| jti | JWT ID — unique token identifier | Omitting jti when you need replay detection |
A minimal payload might look like:
{
"sub": "user-123",
"iss": "https://auth.example.com",
"aud": "https://api.example.com",
"exp": 1735689600,
"iat": 1735686000
}
Cyberway shows registered claims with hover tooltips while you inspect a token — useful when you are learning which claim is which.
Algorithms: HS256 vs RS256 vs ES256
HMAC algorithms (HS256, HS384, HS512) use a shared secret. The same secret signs and verifies. They are simple for internal services but dangerous if the secret leaks — any holder can mint tokens.
RSA algorithms (RS256, and RS384/RS512) use a private key to sign and a public key to verify. The API only needs the public key, which is safer for distributed verification.
ECDSA algorithms (ES256, etc.) offer smaller signatures with comparable security to RSA at similar key strengths.
Never accept alg: none in production verifiers. Never let the token header alone decide which algorithm to use without an allowlist — that opens algorithm confusion attacks.
When choosing: use HS256 only when one trusted party holds the secret; prefer RS256 or ES256 when many services verify but only the auth service signs.
Token lifecycle
A typical access-token lifecycle looks like this:
- Issue — user authenticates; auth server signs a JWT with short
exp(e.g. 15 minutes). - Use — client sends
Authorization: Bearer <token>; API verifies signature,exp,iss, andaud. - Expire — after
exp, verifier rejects; client uses a refresh token (often opaque, server-stored) to obtain a new access token. - Revoke — on logout or compromise, invalidate refresh tokens server-side; access tokens remain valid until
expunless you maintain a blocklist.
Understanding this flow helps you debug "it worked five minutes ago" incidents — often exp, clock skew, or a rotated signing key is involved.
Verification vs decoding
Decoding reads header and payload from Base64URL. It proves nothing about authenticity.
Verification cryptographically validates the signature against your key material and checks time claims (exp, nbf) and usually iss and aud.
Always verify on the server that protects your APIs. Client-side verification in Cyberway's optional verify panel is for learning and debugging — not a replacement for server-side checks.
Minimal verification with jose in Node.js:
import { jwtVerify } from "jose";
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
const { payload } = await jwtVerify(token, secret, {
algorithms: ["HS256"],
issuer: "https://auth.example.com",
audience: "https://api.example.com",
});
Common failure modes
These patterns cause most JWT incidents in production:
- Expired
exp— token lifetime elapsed; see JWT expired token errors. alg: noneor algorithm confusion — attacker forges payload; see common JWT security mistakes.- Weak HMAC secrets — offline brute force recovers signing key.
- Skipping
aud/isschecks — token valid for wrong service. - Confusing decode with authenticate — UI shows claims from an untrusted token.
Use the weekly JWT challenge to practice spotting deliberate flaws in public sample tokens.
Key rotation and compromise response
When a signing key may be exposed, rotation is not optional. For HMAC, generate a new secret and invalidate all outstanding tokens — every client must re-authenticate. For RS256/ES256, publish a new key in your JWKS endpoint with a new kid (key id) in the JWT header, keep the old public key available briefly for tokens still in flight, then remove it.
Document your rotation runbook before an incident. During panic, teams that have never rotated keys discover hard-coded secrets in five microservices and a mobile app build pipeline.
Debugging workflow with Cyberway
When a token fails verification in staging:
- Paste it into the Cyberway JWT Decoder — confirm structure and claims visually.
- Check
expandnbfbefore blaming the signing key. - Use the verify panel with your staging secret or public key to reproduce the library error.
- Compare header
algwith your server's allowlist.
This workflow keeps real tokens off third-party servers while you iterate on fixes.
Further reading on standards
The JWT ecosystem spans several RFCs: RFC 7519 (claims), RFC 7515 (JWS signing), and RFC 7517 (JWK key format). When your auth provider publishes a JWKS URL, you are consuming 7517 in practice.
Keep learning
Try the Cyberway JWT Decoder or JWT Generator — both run entirely in your browser.
