JSON Web Tokens (JWTs) are everywhere in modern web development. If you've built an API, used OAuth, or integrated a third-party service, you've almost certainly encountered one. This guide explains what they are, how they work, and the mistakes that trip up most developers.
What Is a JWT?
A JWT is a compact, URL-safe string that carries a set of claims between two parties. It's commonly used for authentication — after a user logs in, the server issues a JWT that the client sends with subsequent requests to prove identity.
Unlike session-based auth where the server stores state, JWTs are stateless. The token itself contains all the information the server needs to validate the request.
JWT Structure: Three Parts
Every JWT consists of three Base64URL-encoded parts separated by dots:
header.payload.signature1. Header
The header declares the token type and signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}Common algorithms include HS256 (HMAC + SHA-256), RS256 (RSA + SHA-256), and ES256 (ECDSA + SHA-256). The choice of algorithm determines how the signature is created and verified.
2. Payload
The payload contains claims — statements about the user and token metadata:
{
"sub": "1234567890",
"name": "Jane Developer",
"email": "jane@example.com",
"role": "admin",
"iat": 1710700800,
"exp": 1710787200
}3. Signature
The signature is created by signing the encoded header and payload with a secret key. For HS256:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)The signature ensures the token hasn't been tampered with. If anyone changes the payload, the signature won't match and the server will reject the token.
Standard Claims
The JWT spec defines several registered claims. None are required, but they're widely used:
| Claim | Name | Description |
|---|---|---|
iss | Issuer | Who created the token |
sub | Subject | Who the token is about (usually a user ID) |
aud | Audience | Who the token is intended for |
exp | Expiration | Unix timestamp when the token expires |
iat | Issued At | Unix timestamp when the token was created |
nbf | Not Before | Token is invalid before this time |
How JWT Authentication Works
- 1The user sends credentials (email + password) to your login endpoint.
- 2The server verifies the credentials, creates a JWT with the user's claims, and signs it with a secret key.
- 3The client stores the JWT (commonly in memory or an
httpOnlycookie) and includes it in theAuthorizationheader of subsequent requests. - 4The server verifies the signature and checks expiration on each request — no database lookup needed.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRGV2ZWxvcGVyIiwiaWF0IjoxNzEwNzAwODAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cCommon Mistakes and Security Pitfalls
Storing JWTs in localStorage
localStorage is accessible to any JavaScript running on the page, making it vulnerable to XSS attacks. Prefer httpOnly cookies — they're not accessible via JavaScript and are sent automatically with requests.
Not Validating the Algorithm
The classic alg: "none" attack works when servers blindly trust the algorithm specified in the header. Always validate that the algorithm matches what your server expects. Most modern JWT libraries handle this, but double-check your configuration.
Setting Tokens That Never Expire
A stolen token without an expiration is a permanent key. Always set a reasonable exp claim. For access tokens, 15-60 minutes is common. Use refresh tokens for longer sessions.
Putting Sensitive Data in the Payload
The payload is encoded, not encrypted. Anyone can decode it with a Base64 decoder. Never include passwords, API keys, or other secrets in the payload. Use our JWT Decoder to see how easy it is to read the payload of any JWT.
When to Use JWTs (and When Not To)
Good use cases:
- Stateless API authentication across microservices
- Single sign-on (SSO) between applications
- Short-lived authorization tokens (OAuth 2.0 access tokens)
Consider alternatives when:
- You need to revoke tokens immediately (JWTs are valid until they expire)
- You're building a simple server-rendered app (session cookies are simpler)
- Token payload would be very large (JWTs are sent with every request)
Deploying a JWT-authenticated API?
Cloudways provides managed hosting with built-in SSL, automated backups, and server-level firewalls to protect your auth endpoints. Deploy on DigitalOcean, AWS, or GCP without managing servers yourself.
Try It Yourself
Paste any JWT into our JWT Decoder to instantly see its header, payload, and expiration status — all decoded locally in your browser. You can also use the Base64 Decoder to manually decode individual JWT parts, or the Hash Generator to explore the SHA-256 algorithm used in JWT signatures.