JWT Tokens Explained: How JSON Web Tokens Work
A complete guide to JSON Web Tokens โ the three-part structure, signing algorithms, security considerations, and when to use JWTs vs sessions.
ToolNest Team
November 28, 2025
What Is a JWT?
A JSON Web Token (JWT, pronounced "jot") is a compact, self-contained token format used for securely transmitting information between parties. JWTs are most commonly used for authentication โ after a user logs in, the server issues a JWT, and the client includes it in subsequent requests to prove identity.
The specification is defined in RFC 7519.
The Three-Part Structure
A JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Three sections separated by dots: header.payload.signature
Header โ Specifies the token type and signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
Payload โ Contains the claims (data):
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622,
"role": "admin"
}
Signature โ Verifies the token hasn't been tampered with:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret_key
)
Both header and payload are Base64url-encoded (not encrypted). The signature is a cryptographic hash that can only be produced with the secret key.
Standard JWT Claims
The JWT spec defines "registered claims" โ reserved field names with specific meanings:
| Claim | Name | Description |
|---|---|---|
iss |
Issuer | Who created the token (e.g., "api.myapp.com") |
sub |
Subject | Who the token is about (usually user ID) |
aud |
Audience | Who the token is intended for |
exp |
Expiration | When the token expires (Unix timestamp) |
iat |
Issued At | When the token was issued |
jti |
JWT ID | Unique identifier for the token |
Always include exp โ tokens without expiry are a security risk.
Signing Algorithms
HS256 (HMAC-SHA256): Symmetric โ same secret key used to sign and verify. Fast and simple. Use when the same server signs and verifies (single-service APIs).
RS256 (RSA-SHA256): Asymmetric โ private key signs, public key verifies. Use when multiple services need to verify tokens without knowing the signing key (microservices, third-party verification).
ES256 (ECDSA-SHA256): Like RS256 but uses elliptic curve cryptography. Produces smaller signatures with equivalent security.
Never use "alg": "none" โ This disables signature verification entirely. Historical JWT libraries had a vulnerability where attackers could set alg to "none" and forge arbitrary tokens. Reject tokens with algorithm "none".
JWT vs Session Tokens
Session tokens: Server stores session data in a database. Client sends opaque session ID. Server must look up the session on every request.
JWTs: Server is stateless โ no session lookup required. The token itself contains all necessary data, and the signature proves its authenticity.
| Aspect | JWT | Session |
|---|---|---|
| Server state | Stateless | Stateful (session store) |
| Scalability | Easy horizontal scaling | Requires shared session store |
| Revocation | Difficult | Easy (delete session) |
| Token size | Larger | Small (just an ID) |
| Offline verification | Yes (with public key) | No |
JWTs are ideal for stateless APIs and microservices. Session tokens are better when you need easy revocation (e.g., "sign out all devices").
Security Considerations
Don't store sensitive data in the payload. JWT payloads are Base64-encoded, not encrypted. Anyone who intercepts the token can read the payload without knowing the secret. Never put passwords, SSNs, credit card numbers, or other sensitive data in a JWT.
Always set expiration. Short-lived tokens (15 minutes to 1 hour) reduce the window of damage if a token is stolen. Use refresh tokens for long-lived sessions.
Validate all claims server-side. Check exp, iss, aud. Don't trust user-provided data in the payload without verification.
Choose secure storage. Where to store JWTs in browsers is debated:
- localStorage: Vulnerable to XSS (JavaScript can read it)
- httpOnly cookies: Not accessible to JavaScript; immune to XSS; vulnerable to CSRF (mitigate with SameSite=Strict and CSRF tokens)
- Memory only: Most secure against XSS; lost on page refresh
Use HTTPS always. JWTs sent over HTTP can be intercepted in transit.
Implement refresh token rotation. When a refresh token is used, issue a new one and invalidate the old one. If a refresh token is stolen and used, the legitimate user's rotation will detect the breach.
Decoding Without Verification
You can decode the header and payload of any JWT without knowing the secret โ they're just Base64url-encoded JSON. This is useful for debugging. Only verification (checking the signature) requires the secret.
Use our free JWT Decoder to inspect the contents of any JWT token instantly.
Share this article