Understanding JWT Authentication
Learn how JSON Web Tokens work, what the three parts mean, how signatures are verified, and the most common security mistakes developers make with JWTs.
What is a JSON Web Token?
A JSON Web Token (JWT) is a compact, URL-safe string used to represent claims between two parties. Instead of storing session state on the server, you issue a signed token to the client, which sends it back with every request.
A JWT consists of three Base64url-encoded parts separated by dots:
- Header — the token type and signing algorithm (e.g. `{"alg":"HS256","typ":"JWT"}`)
- Payload — the claims, such as user ID, roles, and expiry time
- Signature — a cryptographic value that prevents tampering
The format looks like: `xxxxx.yyyyy.zzzzz`
Anatomy of the Header and Payload
The header specifies the algorithm used to sign the token. Common values are `HS256` (HMAC-SHA256, symmetric) and `RS256` (RSA-SHA256, asymmetric).
The payload contains claims — statements about the user or token itself. Standard registered claims include:
- iss (issuer) — who created the token
- sub (subject) — who the token is about, usually a user ID
- exp (expiration) — Unix timestamp after which the token is invalid
- iat (issued at) — when the token was created
- aud (audience) — the intended recipient
You can also add custom claims like `{"role": "admin", "plan": "pro"}`. Keep the payload small — it's sent with every request.
How the Signature is Verified
The signature binds the header and payload together using a secret key. For HMAC-SHA256, it's computed as:
`HMAC-SHA256(base64url(header) + '.' + base64url(payload), secret)`
When a server receives a JWT, it re-computes the signature using its own key and compares it to the one in the token. If they match, the payload is trustworthy.
The "none" algorithm vulnerability: some early JWT libraries accepted `{"alg":"none"}` as a valid header, meaning no signature was required. An attacker could forge any payload. Always explicitly allow only specific algorithms and never trust the algorithm from the token header itself.
// Node.js — always verify with explicit algorithm
const jwt = require('jsonwebtoken');
const payload = jwt.verify(token, process.env.JWT_SECRET, {
algorithms: ['HS256'], // explicit allowlist — never omit this
});JWTs Are Not Encrypted
This is the most misunderstood aspect of JWTs. Base64url encoding is not encryption — anyone who intercepts the token can decode the header and payload instantly. The signature only proves the token hasn't been modified; it does not hide the contents.
Never put sensitive data (passwords, credit card numbers, PII) in a JWT payload unless you encrypt the entire token (JWE — JSON Web Encryption).
You can verify this yourself: paste any JWT into the DevForge JWT Decoder and you'll see the full header and payload without needing any key.
Common JWT Security Mistakes
- Storing JWTs in localStorage — JavaScript can read it, making it vulnerable to XSS attacks. Prefer HttpOnly cookies.
- Not validating `exp` — always check expiry on the server, even if your JWT library claims to do it automatically.
- Accepting weak algorithms — reject `none`, and choose between HS256 (shared secret, simpler) and RS256 (key pair, better for microservices).
- Bloated payloads — JWTs are sent on every request. A 10 KB payload adds measurable overhead at scale.
- No token revocation strategy — JWTs are stateless, so there's no built-in revocation. Use short expiry times (15 minutes) and refresh tokens, or maintain a token blocklist.
Inspecting JWTs with the DevForge JWT Decoder
When debugging authentication issues, you often need to quickly inspect a token's claims and check whether it has expired. The DevForge JWT Decoder lets you paste any JWT and instantly see the decoded header, payload claims, and expiration status — without writing a single line of code.
It's useful for checking what claims your auth server is actually issuing, verifying that `exp` is set correctly, and confirming the algorithm before implementing your verification code.
Try it on DevForge
Free online tools related to this tutorial — no signup required.
Related Tutorials
SSL/TLS Handshake Deep Dive
Learn how HTTPS connections are established. Understand the TLS handshake, certificates, cipher suites, and how encryption protects your data.
REST API Design Basics
Learn how to design clean, consistent REST APIs. Covers resource naming, HTTP methods, status codes, pagination, and versioning.
SSH Key Authentication
Set up SSH key-based authentication. Generate key pairs, configure servers, manage multiple keys, and harden your SSH setup.