What JWT stands for
JWT stands for JSON Web Token, pronounced "jot". It is a compact, URL-safe format for transmitting structured information between parties as a signed token. JWTs are most commonly used for authentication and authorization — after a user logs in, the server issues a JWT and the client includes it in subsequent requests to prove identity.
The three-part structure
A JWT consists of three parts, separated by dots:
header.payload.signature
Each part is Base64URL-encoded. A real JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header
The header is a JSON object that identifies the token type and the signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
alg specifies the algorithm used to sign the token. Common values include HS256 (HMAC with SHA-256), RS256 (RSA signature with SHA-256), and ES256 (ECDSA with SHA-256).
Payload
The payload contains claims — statements about the user and additional metadata:
{
"sub": "1234567890",
"name": "Alice",
"email": "[email protected]",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}
Common standard claims:
| Claim | Meaning |
|---|---|
sub | Subject — the user identifier |
iss | Issuer — who created the token |
aud | Audience — who the token is intended for |
iat | Issued-at — Unix timestamp of creation |
exp | Expiry — Unix timestamp after which the token is invalid |
nbf | Not-before — token is not valid before this timestamp |
You can also include custom claims for application-specific data.
Signature
The signature is computed over the encoded header and payload:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
This is the only part of a JWT that provides security. The signature lets the recipient verify that the token was created by someone who knew the secret key, and that neither the header nor the payload were tampered with after signing.
Critical: decoding is not verification
Decoding a JWT is trivial. Because the header and payload are only Base64URL-encoded (not encrypted), anyone can read them without any secret. You can paste a JWT into a decoder and see its contents immediately.
Verifying a JWT is a different operation. Verification checks the signature against the server's secret key. If the payload has been tampered with, the signature will not match and the token should be rejected.
Do not trust the claims in a JWT just because you can read them. Always verify the signature server-side before using the claims for authorization.
The JWT Decoder tool lets you inspect the header and payload for debugging and learning purposes. It does not — and cannot — verify the signature without the secret key.
How JWTs are typically used
- User logs in with credentials.
- Server validates the credentials and issues a signed JWT containing the user's ID and roles.
- Client stores the JWT (in memory, localStorage, or an httpOnly cookie — each has different security trade-offs).
- Client sends the JWT in the
Authorizationheader on each request:Authorization: Bearer <token>. - Server verifies the signature and reads the claims to identify the user and check permissions — no database lookup required.
Security considerations
Never put sensitive data in the payload. The payload is readable by anyone who has the token. Do not include passwords, credit card numbers, or other secrets in JWT claims.
Use short expiry times. JWTs cannot be invalidated after issuance (unless you maintain a blocklist, which defeats part of the stateless benefit). A short exp limits the damage if a token is stolen.
Validate the alg claim server-side. A known attack involves changing the alg to none, which disables signature verification on some older libraries. Always specify the expected algorithm explicitly in your verification code.
Prefer RS256 or ES256 over HS256 for public APIs. HMAC (HS256) uses a shared secret — both issuer and verifier must know it. RSA/ECDSA (RS256/ES256) use a private key to sign and a public key to verify, so verifiers never need to know the private key.
Store JWTs securely. Tokens in localStorage are accessible to JavaScript, making them vulnerable to XSS attacks. Tokens in httpOnly cookies are not directly accessible to JavaScript but require CSRF protection.