JWT Explained: How JSON Web Tokens Work
JSON Web Tokens (JWT) are compact, URL‑safe tokens that carry claims used for authentication and authorization. A JWT consists of a header, payload, and signature, and can be decoded without verification. Proper validation—including signature, issuer, audience, and expiration—is essential to secure…
When building RESTful services, developers often rely on a token‑based approach to authenticate users. JSON Web Tokens, or JWTs, are the most popular format for carrying authentication claims across the internet. Although a JWT may look like a long, unreadable string, it is simply a base64‑encoded representation of three distinct parts: the header, the payload, and the signature.
What Exactly Is a JWT?
A JWT is a compact, self‑contained token that can be transmitted in HTTP headers, query strings, or cookies. It is designed to be stateless, meaning the server does not need to keep session data in memory; all the information required to verify the user’s identity is embedded in the token itself. The typical flow is:
- User logs in with credentials.
- The authentication server validates the credentials and issues a JWT.
- The client stores the token (often in localStorage or an HTTP‑only cookie).
- For every subsequent request to a protected endpoint, the client sends the token in the
Authorization: Bearer <token>header. - The API server verifies the signature and claims before granting access.
Structure of a JWT
A signed JWT is composed of three base64url‑encoded segments separated by periods:
- Header – describes the token type and signing algorithm, e.g.
{"alg":"HS256","typ":"JWT"}. - Payload – contains the claims, such as user ID, role, and timestamps. Standard claims include
sub(subject),iss(issuer),aud(audience),exp(expiration),iat(issued at),nbf(not before), andjti(JWT ID). Applications may also add custom claims. - Signature – a cryptographic hash of the header and payload, generated using a secret key (HMAC) or a private key (RSA/ECDSA). The signature ensures the token has not been altered.
Because the header and payload are only base64url‑encoded, anyone who intercepts the token can decode them and read the claims. Therefore, a JWT should never contain sensitive data such as passwords or secret keys. Encoding is not encryption.
Decoding vs. Verifying a JWT
Decoding a JWT simply means converting the base64url segments back into readable JSON. This step does not guarantee the token is trustworthy. Verification, on the other hand, checks the signature and validates that the claims meet the application's security requirements. A token might decode to {"role":"admin"}, but if the signature does not match the secret key, the server must reject it.
Common Use Patterns: Access and Refresh Tokens
Most modern authentication systems employ two types of tokens:
- Access Token – short‑lived (minutes to an hour) and used for API calls.
- Refresh Token – long‑lived (days or weeks) and stored securely. When the access token expires, the client exchanges the refresh token for a new access token.
Using a short‑lived access token limits the damage if the token is compromised, while the refresh token allows the user to remain logged in without re‑entering credentials.
Common Security Pitfalls
- Assuming a decoded payload is trustworthy. Always validate the signature and required claims on the server.
- Storing confidential data in the payload. Keep passwords, secrets, or highly sensitive information out of the token.
- Issuing access tokens with overly long lifetimes. Short lifespans reduce exposure.
- Skipping issuer (
iss) and audience (aud) validation. These claims help confirm the token originates from a trusted source and is intended for your API. - Accepting arbitrary signing algorithms. Configure the server to accept only the algorithms your system uses.
Debugging JWT Issues
When an API returns a 401 Unauthorized error, start with this checklist:
- Token structure – Does it have three parts?
- Header – Is the algorithm correct?
- Payload – Are required claims present?
- Expiration – Has
exppassed? - Issuer – Does
issmatch your trusted issuer? - Audience – Is
audset to your API? - Signature – Does it verify with the secret or public key?
- Permissions – Does the user’s role grant access to the endpoint?
Tools like jwt.io can decode tokens for quick inspection, but never paste production tokens into public decoders unless you understand the privacy implications.
Why JWTs Matter for Modern Web Development
JWTs enable stateless, scalable authentication that works seamlessly across microservices, mobile apps, and single‑page applications. By embedding claims directly in the token, services can verify identity without repeated database lookups, improving performance and reducing infrastructure complexity.
Key Takeaways
- A JWT is a header, payload, and signature; decoding does not equal verification.
- Never store sensitive data in the payload; encoding is not encryption.
- Validate signature, issuer, audience, and expiration on the server.
- Use short‑lived access tokens with long‑lived refresh tokens for a balanced security posture.
- Employ a debugging checklist to quickly resolve authentication failures.
Frequently Asked Questions
- Can I use JWTs without HTTPS? No. Transmitting JWTs over an insecure channel exposes them to interception and replay attacks.
- What if my JWT is expired? The client should use the refresh token to request a new access token. If no refresh token is available, the user must re‑authenticate.
- How do I rotate the signing key? Implement key rotation by supporting multiple keys and including a key identifier (
kid) in the header. - Do I need to store the JWT on the server? No. The server only needs the secret or public key to verify signatures.
Why it matters
JWTs provide a stateless, scalable method for authenticating users across distributed systems, reducing server load and simplifying token management.
Key points
- JWTs consist of header, payload, and signature; decoding is not verification
- Never embed sensitive data in the payload—encoding is not encryption
- Always validate signature, issuer, audience, and expiration on the server
- Use short‑lived access tokens with refresh tokens for security
- Follow a systematic debugging checklist for authentication issues
Frequently asked questions
Can I use JWTs without HTTPS?
No. Transmitting JWTs over an insecure channel exposes them to interception and replay attacks.
What if my JWT is expired?
The client should use the refresh token to request a new access token. If no refresh token is available, the user must re‑authenticate.
How do I rotate the signing key?
Implement key rotation by supporting multiple keys and including a key identifier (kid) in the header.
Do I need to store the JWT on the server?
No. The server only needs the secret or public key to verify signatures.




