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?
Related: AI Security Checklist