JWT Authentication Explained: How JSON Web Tokens Work
JSON Web Tokens (JWTs) are everywhere in modern web development — used for authentication, authorization, and secure information exchange between services. Yet many developers use them without fully understanding how they work, which leads to security vulnerabilities and incorrect implementations.
This guide explains JWTs from first principles: their structure, how signing works, when to use them, and how to use them safely.
What Is a JWT?
A JSON Web Token is a compact, URL-safe means of representing claims between two parties. It is defined by RFC 7519.
A JWT looks like this:
It has three parts separated by dots: Header . Payload . Signature
The Three Parts of a JWT
1. Header
The header is a Base64URL-encoded JSON object that declares the token type and signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
Common algorithms: HS256 (HMAC-SHA256, symmetric), RS256 (RSA-SHA256, asymmetric), ES256 (ECDSA-SHA256, asymmetric).
2. Payload
The payload contains the claims — statements about the user or system, plus metadata. Standard registered claims include:
sub— Subject (who the token is about, e.g. user ID)iss— Issuer (who created the token)aud— Audience (who the token is intended for)exp— Expiry time (Unix timestamp)iat— Issued-at timejti— JWT ID (unique identifier, useful for revocation)
{
"sub": "user_abc123",
"iss": "https://auth.example.com",
"aud": "https://api.example.com",
"exp": 1735689600,
"iat": 1735686000,
"name": "Jane Smith",
"role": "admin"
}
3. Signature
The signature verifies that the token hasn't been tampered with. It is computed as:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
For HS256, the same secret is used to both sign and verify. For RS256, a private key signs the token and the corresponding public key verifies it — this is generally more secure for distributed systems.
How JWT Authentication Works (Step by Step)
- Login: User sends credentials (username + password) to the auth server
- Token issuance: Server validates credentials and returns a signed JWT
- Client storage: Client stores the JWT (localStorage, sessionStorage, or an HttpOnly cookie)
- API requests: Client sends the JWT in the
Authorizationheader:Bearer <token> - Verification: Server validates the signature, checks expiry (
exp), and reads claims - Response: If valid, server processes the request; if expired or invalid, returns 401
Signing Algorithms Compared
| Algorithm | Type | Use Case | Recommendation |
|---|---|---|---|
| HS256 | Symmetric | Single service | OK if secret is strong and private |
| RS256 | Asymmetric | Microservices | Preferred — public key can be shared |
| ES256 | Asymmetric | High-security | Best — smaller keys, same security as RS256 |
| none | None | Never | Never use — tokens can be forged |
JWT Security Best Practices
- Use short expiry times. Access tokens should expire in 15–60 minutes. Use refresh tokens for longer sessions.
- Validate all claims. Always check
exp,iss, andaudon every request — don't just check the signature. - Use RS256 or ES256 over HS256 for services that verify but don't issue tokens.
- Reject the
alg: noneattack. Always specify and enforce the expected algorithm — never accept whatever the token header declares. - Store tokens in HttpOnly cookies rather than localStorage to prevent XSS attacks from stealing tokens.
- Always use HTTPS. JWTs in transit over HTTP are trivially stolen.
- Implement a revocation strategy. JWTs can't be invalidated before expiry by default — use a token blacklist or short expiry + refresh token rotation.
JWT vs Session Tokens
| Aspect | JWT | Session Token |
|---|---|---|
| Storage (server) | Stateless — no server storage needed | Requires session store (DB, Redis) |
| Scalability | Excellent — any server can verify | Requires sticky sessions or shared store |
| Revocation | Hard — must wait for expiry | Easy — delete from store |
| Size | Larger (hundreds of bytes) | Small (random string) |
| Best for | Microservices, APIs | Traditional web apps |
Frequently Asked Questions
What does JWT stand for?
JWT stands for JSON Web Token. It is an open standard (RFC 7519) for securely transmitting information between parties as a signed JSON object.
Can I decrypt a JWT?
Standard JWTs are signed, not encrypted. The payload is only Base64URL-encoded and can be decoded by anyone. If you need encrypted JWTs, use JWE (JSON Web Encryption) instead.
How do I invalidate a JWT before it expires?
Options include: maintaining a token blacklist (check against it on each request), using very short expiry times with refresh token rotation, or encoding a token version in the payload and incrementing it on logout.