A JSON Web Token (JWT) is a compact, URL-safe string of three Base64URL-encoded parts, header.payload.signature, that carries signed claims about a user so a server can verify who they are without a database lookup. Defined by RFC 7519 (with the signature mechanics in RFC 7515, JWS), the header names the algorithm, the payload holds the claims like sub, exp, and iat, and the signature is computed over the header and payload with a secret (HS256) or a private key (RS256). Because the signature covers the exact bytes of the first two parts, changing a single character invalidates the token, but the payload itself is only encoded, not encrypted, so anyone holding the token can read it.
That is the definition an AI Overview will hand you. What it can't show you is the shape of the thing, how the three parts actually fit together, how a login turns into a bearer token on every request, and where the security lands you in trouble. The diagrams, algorithm table, and decision guidance below make those concrete. If you want to pull a real token apart right now, our JWT Decoder runs entirely in your browser.
The Anatomy of a JWT
Every JWT is three chunks joined by dots. The first two are just Base64URL-encoded JSON you can read; the third is the cryptographic seal that makes the first two trustworthy.
What Is a JWT?
A JWT is a compact, URL-safe token format that securely transmits information between parties as a JSON object. The information can be verified and trusted because it's digitally signed.
JWTs are commonly used for:
- Authentication: After login, each subsequent request includes the JWT, allowing access to routes, services, and resources
- Information exchange: JWTs can securely transmit information between parties because they're signed
JWT Structure
A JWT consists of three parts separated by dots: header.payload.signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header
The header typically contains the token type (JWT) and the signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
Payload
The payload contains claims---statements about the user and additional metadata:
{
"sub": "1234567890",
"name": "John Doe",
"email": "john@example.com",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}
Registered claims are predefined:
iss(issuer): Who issued the tokensub(subject): Who the token is about (usually user ID)aud(audience): Who the token is intended forexp(expiration): When the token expiresiat(issued at): When the token was creatednbf(not before): Token not valid before this time
Custom claims can include any data you need, like user roles or permissions.
Signature
The signature verifies the token wasn't tampered with:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
How JWT Authentication Works
- User logs in with credentials
- Server validates credentials and generates a JWT
- JWT is returned to the client (stored in localStorage, sessionStorage, or cookie)
- Client includes JWT in the Authorization header for subsequent requests
- Server validates JWT signature and grants access
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
The key insight is that after the initial login, the server keeps no session record. On every later request it simply re-verifies the signature and reads the claims. That statelessness is what makes JWTs scale across many servers, and it is also why you can't revoke one on demand.
Signing Algorithms
Symmetric algorithms (HS256, HS384, HS512) use the same secret key to sign and verify. Simple but requires secure key distribution.
Asymmetric algorithms (RS256, RS384, RS512, ES256) use a private key to sign and a public key to verify. Better for distributed systems where multiple services need to verify tokens.
| Algorithm | Type | Signs with | Verifies with | Best for |
|---|---|---|---|---|
| HS256 / HS384 / HS512 | Symmetric (HMAC) | Shared secret | Same shared secret | One trusted service that both issues and checks tokens |
| RS256 / RS384 / RS512 | Asymmetric (RSA) | Private key | Public key | Many services verifying tokens they must not be able to forge (SSO, microservices) |
| ES256 / ES384 | Asymmetric (ECDSA) | Private key | Public key | Same as RS256 but smaller keys/signatures — good for mobile and high-throughput APIs |
| EdDSA (Ed25519) | Asymmetric | Private key | Public key | Modern deployments wanting fast, misuse-resistant signatures |
| none | Unsigned | nothing | nothing | Never in production — an unsigned token is forgeable by anyone |
| Which should I use? | — | — | — | Single backend → HS256. Multiple independent verifiers → RS256 or ES256. Never accept none or let the client dictate alg. |
JWT Security Best Practices
Set Short Expiration Times
JWTs can't be revoked once issued. Short expiration times (15 minutes to 1 hour) limit the window of vulnerability if a token is compromised.
Use HTTPS Only
JWTs are credentials. Always transmit them over HTTPS and set the Secure cookie flag if storing in cookies.
Don't Store Sensitive Data in Payload
The payload is only base64-encoded, not encrypted. Anyone can decode and read it. Never include passwords, API keys, or sensitive personal data.
Validate Everything
Always verify:
- The signature is valid
- The token hasn't expired (
exp) - The issuer is correct (
iss) - The audience is correct (
aud)
Use Strong Secrets
For HMAC algorithms, use secrets at least 256 bits long. Generate them securely---never use simple phrases.
Common JWT Vulnerabilities
Algorithm confusion: Attackers change alg to none or switch from RS256 to HS256 using the public key as the secret. Always explicitly specify allowed algorithms when verifying.
Missing signature validation: Never skip signature verification. A token without validation is just a base64 string anyone can create.
Token sidejacking: If tokens are stored insecurely (accessible via XSS), attackers can steal them. Use HttpOnly cookies or secure storage.
Long expiration times: Tokens valid for days or weeks give attackers a large window to use stolen tokens.
When to Use JWTs
Good use cases:
- Stateless authentication across multiple services
- Single sign-on (SSO)
- Short-lived access tokens
- Mobile app authentication
Consider alternatives when:
- You need to revoke tokens immediately
- Sessions are long-lived
- You're only authenticating with one server
Decode and Inspect JWTs
Use our JWT Decoder to:
- Decode any JWT without the secret
- View header and payload claims
- Check expiration status
- Identify the signing algorithm
The decoder runs entirely in your browser---your tokens are never sent to any server.
Key Takeaways
- JWTs have three parts: header, payload, and signature
- The payload is encoded, not encrypted---don't store secrets
- Always validate signatures and expiration
- Use short expiration times since JWTs can't be revoked
- Choose the right signing algorithm for your architecture
JWTs provide a powerful, flexible authentication mechanism when implemented correctly. Understanding their structure and security implications is essential for building secure applications.