JWT Debugger

Decode, encode, and verify JSON Web Tokens (JWT).

Free Online JWT Debugger & Decoder

JWTs power authentication in modern APIs, but their Base64-encoded structure makes them opaque at a glance. Dokall decodes the header and payload, validates structure, and helps you encode or verify tokens during development.

Debug OAuth flows, inspect session tokens, and test signature verification - all in your browser. Never paste production secrets on untrusted sites; Dokall processes tokens client-side.

How JWT Authentication Works

When a user logs in, the server creates a JWT containing the user's identity and permissions, signs it with a secret key, and returns it. On every subsequent request, the client sends the JWT - typically in the Authorization header as Bearer <token>. The server verifies the signature without querying a session store.

This stateless design means any server that holds the signing key can validate the token independently. That makes JWTs popular in microservice architectures, single-page applications, and mobile APIs where the authentication server and the resource server may be different machines.

JWT Structure: Header, Payload, Signature

A JWT is three Base64url-encoded JSON objects separated by dots: header.payload.signature.

The header declares the token type (always JWT) and the signing algorithm, for example {"alg": "HS256", "typ": "JWT"}. The payload carries claims - key-value pairs that describe the user or session. Claims can be registered (defined by the spec), public (custom but collision-resistant), or private (agreed between parties). The signature is produced by signing the encoded header and payload with a secret or private key. Anyone with the corresponding key can verify the token has not been altered.

When you paste a token into this debugger, it splits on the dots, decodes each part, and displays the JSON. No secret is needed to read the header and payload - only to verify the signature.

Signature Algorithms: HS256 vs RS256 vs ES256

HS256 (HMAC + SHA-256) is a symmetric algorithm. The same secret key signs and verifies. It is fast and simple, but every service that needs to verify tokens must know the secret. If one service is compromised, the key is exposed.

RS256 (RSA + SHA-256) is asymmetric. A private key signs the token and a public key verifies it. Only the auth server needs the private key - downstream services use the public key, which is safe to distribute. RS256 keys are larger (2048+ bits) and signing is slower, but verification is fast.

ES256 (ECDSA + P-256) is also asymmetric but uses elliptic curve cryptography. Keys are much smaller than RSA (256-bit vs 2048-bit) and operations are faster, making ES256 a good default for new systems. Most JWT libraries and cloud providers support it.

Choose HS256 for simple single-server setups. Choose RS256 or ES256 when multiple services verify tokens or when you publish a JWKS endpoint.

Standard JWT Claims Reference

The JWT specification (RFC 7519) defines seven registered claims. None are mandatory, but using them consistently helps interoperability.

iss (issuer) identifies who created and signed the token, typically a URL like https://auth.example.com. sub (subject) identifies the principal - usually a user ID. aud (audience) specifies the intended recipient, often the API domain. exp (expiration time) is a Unix timestamp after which the token must be rejected. iat (issued at) records when the token was created. nbf (not before) prevents the token from being used before a specific time. jti (JWT ID) is a unique identifier useful for one-time tokens or revocation lists.

Beyond registered claims, you can add any custom data your application needs - roles, permissions, tenant IDs, email addresses. Just keep the payload small. Every byte increases the size of every HTTP request that carries the token.

JWT vs Session-Based Authentication

Session-based auth stores state on the server. When a user logs in, the server creates a session record (in memory, a database, or Redis), assigns a session ID, and sends it to the client as a cookie. Each request includes the cookie, and the server looks up the session. Revoking access is instant - delete the session.

JWT auth is stateless. The token itself contains all the information the server needs. No database lookup on each request, no shared session store across servers. The downside: you cannot truly revoke a JWT before it expires without maintaining a blocklist, which partially negates the stateless benefit.

Sessions are simpler and better when you need instant revocation (banking, admin panels). JWTs are better for distributed systems, cross-domain APIs, and mobile clients where cookies are inconvenient. Many production systems combine both - short-lived JWTs for API access with a server-side refresh token that can be revoked.

Common JWT Errors and How to Fix Them

"Token expired" means the current time has passed the exp claim. Check whether your server clock is synchronized (NTP drift is a common cause in containers). If the token lifetime is too short, increase it or implement a refresh token flow.

"Invalid signature" means the verification key does not match the signing key. This often happens when deploying with environment-specific secrets and the wrong secret is loaded, when rotating keys without updating all services, or when copying a token between environments.

"Token not yet valid" triggers when the current time is before the nbf claim. This is usually a clock skew issue between the issuing server and the verifying server. Most JWT libraries accept a small clock tolerance (typically 30-60 seconds).

"Malformed JWT" means the token does not have three dot-separated parts or a part is not valid Base64url. Check for accidental whitespace, line breaks, or truncation when copying tokens from logs or emails.

JWT Security Best Practices

The payload is encoded, not encrypted. Anyone who intercepts a JWT can read its claims. Never put passwords, credit card numbers, or other secrets in the payload.

Use short expiration times - 15 minutes for access tokens is a common choice. Pair them with longer-lived refresh tokens stored securely on the server. This limits the damage window if a token is stolen.

For HS256, your secret should be at least 256 bits of cryptographic randomness. A short passphrase is vulnerable to brute-force attacks. Use a key generator to create proper secrets.

Always validate the alg claim server-side. The "algorithm confusion" attack tricks a server into treating an RS256 token as HS256, using the public key as the HMAC secret. Modern libraries protect against this, but explicit algorithm configuration is still recommended.

Prefer httpOnly, Secure, SameSite cookies for storing JWTs in browsers. localStorage is accessible to any JavaScript on the page, making it vulnerable to XSS attacks. Cookies with proper flags are immune to XSS token theft.

Frequently Asked Questions

What is a JSON Web Token (JWT)?
A JSON Web Token is a compact, URL-safe token format defined in RFC 7519. It carries a set of claims as a JSON object, signed with a secret (HMAC) or a public/private key pair (RSA, ECDSA). JWTs are widely used for authentication and authorization in web APIs. The token has three parts - header, payload, and signature - separated by dots.
Is it safe to decode JWTs in an online tool?
Dokall decodes tokens entirely in your browser. Nothing is sent to a server. For development and debugging, browser-based decoders are safe and convenient. That said, avoid pasting production tokens that contain real user data on any public website - even a client-side one - if your browser extensions or clipboard manager could leak them.
Can you read a JWT without the secret key?
Yes. The header and payload are only Base64url-encoded, not encrypted. Anyone can decode and read them. The secret key is only needed to verify the signature - to confirm the token has not been tampered with. This is why you should never store sensitive data in the JWT payload.
What is the difference between HS256 and RS256?
HS256 is symmetric - the same secret key signs and verifies the token. RS256 is asymmetric - a private key signs and a separate public key verifies. Use HS256 when only one server issues and verifies tokens. Use RS256 or ES256 when multiple services need to verify tokens without knowing the signing secret.
Why does my JWT show as expired?
The token's exp (expiration) claim is a Unix timestamp. If the current time exceeds it, the token is expired. Common causes: the token lifetime is too short for your use case, the server clock is out of sync (NTP issues in containers), or the token was issued hours ago and has naturally expired. Fix by adjusting token lifetime, syncing clocks, or implementing a refresh token flow.
Should I store JWTs in localStorage or cookies?
Prefer httpOnly, Secure, SameSite cookies. localStorage is accessible to any JavaScript running on the page, so a single XSS vulnerability can steal the token. httpOnly cookies cannot be read by JavaScript at all. The trade-off is that cookies are sent automatically with every request (including to subdomains), so configure the cookie domain and path carefully.
How do I revoke a JWT before it expires?
JWTs are stateless by design, so there is no built-in revocation. Common strategies: keep access tokens short-lived (5-15 minutes) and use server-side refresh tokens that can be deleted, maintain a blocklist of revoked token IDs (jti claims) checked on each request, or use a token version counter in the database and reject tokens with an old version.
What happens if my JWT secret key is leaked?
Anyone with the secret can forge valid tokens with any claims - effectively impersonating any user. Immediately rotate the secret key, which will invalidate all existing tokens. Users will need to re-authenticate. For HS256, change the secret. For RS256/ES256, generate a new key pair and update your JWKS endpoint. Use key rotation with overlapping validity periods to avoid a hard cutoff.