Blog post
JWT Explained: JSON Web Tokens Complete Guide
Understand JSON Web Tokens (JWT) — structure, signing algorithms, validation, and security best practices with code examples.
Shashank Jain
Author


Article
What Is a JWT?
A JSON Web Token (JWT) is a compact, URL-safe token for transmitting claims between parties. It's most commonly used for authentication and authorization in web APIs. A JWT proves to a server that a user is who they claim to be — without the server storing session state.
JWT Structure
A JWT has three Base64URL-encoded parts separated by dots:
header.payload.signature
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIn0.abc123
Header
{
"alg": "HS256",
"typ": "JWT"
}
Payload (Claims)
{
"sub": "user123",
"name": "Alice Smith",
"iat": 1718000000,
"exp": 1718086400,
"roles": ["admin", "user"]
}
Standard Claims
| Claim | Meaning |
|---|---|
sub | Subject — who the token is about |
iss | Issuer — who created the token |
aud | Audience — intended recipient |
exp | Expiration — Unix timestamp |
iat | Issued at — creation timestamp |
jti | JWT ID — unique identifier |
Creating a JWT in Node.js
const jwt = require('jsonwebtoken');
const token = jwt.sign(
{ sub: 'user123', name: 'Alice', roles: ['admin'] },
process.env.JWT_SECRET,
{ expiresIn: '24h', algorithm: 'HS256' }
);
// Verify
const decoded = jwt.verify(token, process.env.JWT_SECRET);
console.log(decoded.sub); // 'user123'
Creating a JWT in Python
import jwt
import datetime
payload = {
'sub': 'user123',
'name': 'Alice',
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24)
}
token = jwt.encode(payload, 'secret', algorithm='HS256')
decoded = jwt.decode(token, 'secret', algorithms=['HS256'])
print(decoded['sub']) # 'user123'
HS256 vs RS256
| HS256 | RS256 | |
|---|---|---|
| Algorithm | HMAC-SHA256 (symmetric) | RSA-SHA256 (asymmetric) |
| Key | Single shared secret | Private key signs, public key verifies |
| Use case | Single-service auth | Multi-service / third-party verification |
| Key rotation | Must update all services | Rotate private key, publish new public key |
Security Best Practices
- Always verify the signature — never trust an unverified JWT
- Check
expon every request - Use short expiry times (15 min–1 hour) with refresh tokens
- Store tokens in
httpOnlycookies, notlocalStorage - Never put sensitive data in the payload — it's Base64-encoded, not encrypted
- Reject tokens with
alg: none
FAQ
Is JWT encrypted?
No. A standard JWT (JWS) is signed but not encrypted. The payload is Base64URL-encoded, which anyone can decode. Use JWE (JSON Web Encryption) if you need the payload to be confidential.
How do I invalidate a JWT before it expires?
JWTs are stateless by design — you can't invalidate them without state. Common solutions: maintain a token denylist in Redis, use very short expiry times, or rotate the signing secret (invalidates all tokens).
Can I decode a JWT without the secret?
You can decode the header and payload (they're just Base64) without the secret. You cannot verify the signature without the secret. Use jsondecode.com's JWT decoder to inspect any token.
What's the difference between authentication and authorization in JWT context?
Authentication: verifying the token signature proves the user is who they claim to be. Authorization: reading claims in the payload (like roles) determines what they're allowed to do.
Should I use JWT for sessions?
For most web apps, traditional server-side sessions with cookies are simpler and safer. Use JWT when you need stateless auth across multiple services, mobile apps, or third-party integrations.
Keep reading
Recent blogs

Jun 14, 2026
JSON in C#: System.Text.Json and Newtonsoft Complete Guide
Serialize and deserialize JSON in C# using System.Text.Json and Newtonsoft.Json with practical examples.

Jun 14, 2026
JSON to Markdown Table: Convert JSON Arrays Instantly
Convert JSON arrays to Markdown tables in JavaScript, Python, and with the free online tool.

Jun 14, 2026
JSON in TypeScript: Type-Safe Parsing and Validation
Stop using any for JSON in TypeScript — use Zod, type guards, and generics for fully type-safe parsing.