A JWT (JSON Web Token, pronounced “jot”) is a compact, self-contained token used for authentication. After a user logs in, the server creates a JWT and sends it to the client. The client sends it back with every request to prove who they are.
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMjN9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
That long string contains the user’s identity, and it’s cryptographically signed so nobody can tamper with it.
What’s inside a JWT
A JWT has three parts separated by dots:
Header — the algorithm used to sign it
{ "alg": "HS256", "typ": "JWT" }
Payload — the actual data (called “claims”)
{ "user_id": 123, "email": "alice@example.com", "exp": 1710500000 }
Signature — proves the token hasn’t been tampered with
HMACSHA256(base64(header) + "." + base64(payload), secret)
The header and payload are just Base64-encoded (not encrypted). Anyone can decode them. The signature is what makes it secure — only the server with the secret key can create a valid signature.
How authentication works with JWTs
- User sends email + password to
/api/login - Server verifies credentials, creates a JWT with the user’s ID
- Server sends the JWT back to the client
- Client stores it (usually in memory or an httpOnly cookie)
- Client sends the JWT in the
Authorizationheader with every request - Server verifies the signature and reads the user ID from the payload
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
The server never needs to look up a session in a database — all the info is in the token itself. That’s what “stateless” means.
JWT vs. session cookies
| JWT | Session cookie | |
|---|---|---|
| Storage | Client-side | Server-side (database/Redis) |
| Stateless | Yes | No |
| Revocation | Hard (token is valid until it expires) | Easy (delete the session) |
| Scalability | Great (no shared state) | Needs shared session store |
| Best for | APIs, microservices, mobile apps | Traditional web apps |
Common pitfalls
- Don’t store JWTs in localStorage — vulnerable to XSS. Use httpOnly cookies.
- Always set an expiration (
expclaim). Short-lived tokens (15 min) + refresh tokens is the standard pattern. - JWTs are not encrypted — don’t put sensitive data in the payload. Anyone can decode it.
- You can’t easily revoke a JWT — once issued, it’s valid until it expires. For logout, use a token blacklist or short expiration times.
Use our JWT Decoder tool to inspect any JWT.
See also: What is OAuth? | What is HTTPS?