JWT Explained — JSON Web Tokens for Developers | LangStop Blog
JWT Explained — What Developers Need to Know About JSON Web Tokens
JSON Web Tokens (JWT) have become the de facto standard for authentication and information exchange in modern web applications. If you've worked with OAuth 2.0, OpenID Connect, or any modern API, you've likely encountered JWTs.
In this guide, we'll break down everything developers need to know about JWT: how tokens are structured, how authentication works, common security pitfalls, and best practices for production use.
Tip: Decode and inspect JWT tokens safely using the JWT Decoder or create new tokens with the JWT Encoder. 100% client-side—your tokens never leave your browser.
What Is a JWT?
A JSON Web Token (JWT) is a compact, URL-safe token format defined by RFC 7519. It's used to securely transmit information between parties as a JSON object. The information is digitally signed, so it can be verified and trusted.
JWTs are self-contained — they carry all necessary information within the token itself, reducing the need for database lookups.
JWT Structure: The Three Parts
Every JWT consists of three parts separated by dots:
header.payload.signature
1. Header
The header typically contains two parts: the token type (JWT) and the signing algorithm (e.g., HS256 or RS256).
{
"alg": "HS256",
"typ": "JWT"
}This JSON is Base64url-encoded to form the first part of the token.
2. Payload
The payload contains claims — statements about an entity (typically the user) and additional metadata. Claims come in three types:
Registered claims (predefined, recommended):
sub(Subject) — The user or entity the token refers toiss(Issuer) — Who issued the tokenaud(Audience) — Who the token is intended forexp(Expiration) — When the token expires (Unix timestamp)nbf(Not Before) — When the token becomes validiat(Issued At) — When the token was issuedjti(JWT ID) — Unique identifier for the token
Public claims — Custom claims defined by developers, but should be registered in the IANA JSON Web Token Registry or use collision-resistant names.
Private claims — Custom claims agreed upon between parties:
{
"sub": "1234567890",
"name": "Jane Doe",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}3. Signature
The signature is created by taking the encoded header, encoded payload, a secret, and signing them using the algorithm specified in the header.
HMACSHA256(
base64urlEncode(header) + "." +
base64urlEncode(payload),
secret
)
The signature ensures the token hasn't been tampered with. If anyone modifies the header or payload, the signature verification will fail.
Putting It All Together
A complete JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
You can inspect any JWT using the JWT Decoder.
How JWT Authentication Works
Login Flow
- User logs in with credentials (email + password)
- Server validates credentials and creates a JWT
- Server returns the JWT to the client
- Client stores the JWT (localStorage, sessionStorage, or cookie)
- Client sends the JWT in the
Authorization: Bearer <token>header for subsequent requests - Server verifies the JWT signature and extracts user info
- Server processes the request if the token is valid and not expired
Verification Process
When the server receives a JWT:
- Extract the token from the Authorization header
- Split into header, payload, and signature
- Recompute the signature using the header + payload + secret
- Compare computed signature with the provided signature
- Check expiration (
exp) and not-before (nbf) claims - If valid, extract claims and process the request
Signing Algorithms: HS256 vs RS256
| Feature | HS256 (HMAC + SHA-256) | RS256 (RSA + SHA-256) |
|---|---|---|
| Key Type | Symmetric (same key) | Asymmetric (public/private key pair) |
| Secret Management | Single shared secret | Private key signs, public key verifies |
| Key Rotation | Difficult (must update all services) | Easy (rotate private key, share new public key) |
| Performance | Faster (symmetric crypto) | Slower (asymmetric crypto) |
| Use Case | Single service, trusted environment | Microservices, third-party verification |
| Security | Good (keep secret safe) | Better (no shared secret) |
Recommendation: Use RS256 for production systems, especially in microservice architectures. HS256 is acceptable for single-service applications or development.
Common JWT Claims Explained
| Claim | Name | Description |
|---|---|---|
sub |
Subject | Unique identifier for the user (e.g., user ID) |
iss |
Issuer | The issuing server or service |
aud |
Audience | Intended recipient (your API name) |
exp |
Expiration | Unix timestamp when token expires (required for security) |
nbf |
Not Before | Unix timestamp before which token is invalid |
iat |
Issued At | Unix timestamp when token was created |
jti |
JWT ID | Unique identifier to prevent replay attacks |
scope |
Scope | Permissions granted (e.g., read:users write:users) |
Security Best Practices
1. Use HTTPS Always
JWTs can be intercepted if transmitted over HTTP. Always use TLS/SSL.
2. Set Short Expiration Times
Keep exp to 15-60 minutes for access tokens. Use refresh tokens for longer sessions.
3. Validate All Claims
Always verify exp, nbf, iss, and aud claims on every request.
4. Use Strong Secrets
For HS256, use a cryptographically random key of at least 256 bits. For RS256, use at least 2048-bit keys.
5. Never Store Sensitive Data in Payload
The payload is Base64-encoded, not encrypted. Anyone can decode and read it.
6. Implement Token Revocation
Have a mechanism to revoke tokens (e.g., a blocklist or short expiration + refresh tokens).
Common JWT Vulnerabilities
"None" Algorithm Attack
Attackers modify the header to {"alg": "none"} and remove the signature. Always validate that the algorithm matches your expected value.
Weak Secret Key
If your HS256 secret is weak, attackers can brute-force it. Use a cryptographically random key.
Algorithm Confusion
Attackers change RS256 to HS256 and sign with the public key (which is public). Always specify allowed algorithms server-side.
Token Not Checked for Expiry
Always validate exp server-side. Client-side validation is not sufficient.
JWT vs Session-Based Authentication
| Aspect | JWT | Session |
|---|---|---|
| Storage | Client-side (token) | Server-side (session store) |
| Scalability | Excellent (stateless) | Requires shared session store |
| Revocation | Hard (until token expires) | Easy (delete session) |
| Payload Size | Larger (network overhead) | Minimal (only session ID) |
| Implementation | More complex | Simpler |
Debugging JWTs
Use the JWT Decoder to inspect token contents and verify signatures locally. When creating tokens for testing, use the JWT Encoder. Both tools run 100% in your browser — no data is ever uploaded.
Need JWT Tools?
LangStop offers free, privacy-first JWT utilities:
- JWT Decoder — Inspect token headers, payloads, and signatures
- JWT Encoder — Create and sign JWT tokens
All processing happens locally in your browser. No data is ever uploaded.