JWT Token Decoder
Paste any JSON Web Token to instantly decode the header, payload, and claims. Inspect expiry, token status, and registered claim descriptions — no secret key required.
Tokens are decoded on the server — no secret keys are ever sent or processed. The payload is Base64URL-encoded, not encrypted.
Decoding token...
Paste a JWT above and click Decode Token to inspect its contents.
What Is a JSON Web Token?
A JSON Web Token (JWT, pronounced "jot") is an open standard (RFC 7519) for securely transmitting claims between two parties as a compact, URL-safe JSON object. Unlike opaque session tokens, a JWT carries its own data — the server can validate it without a database lookup, making it ideal for stateless, distributed authentication.
Every JWT has three Base64URL-encoded segments separated by dots:
The header names the algorithm. The payload contains the claims (data). The signature proves the header and payload have not been altered. The payload is encoded, not encrypted — anyone who holds the token can read the claims; only the signature prevents tampering.
Header Algorithms
The alg field in the header tells the verifier which algorithm was used to produce the signature.
| alg | Family |
|---|---|
| HS256 | HMAC-SHA256 |
| HS384 | HMAC-SHA384 |
| HS512 | HMAC-SHA512 |
| RS256 | RSA-SHA256 (PKCS1v15) |
| RS384 | RSA-SHA384 |
| RS512 | RSA-SHA512 |
| ES256 | ECDSA P-256 + SHA256 |
| ES384 | ECDSA P-384 + SHA384 |
| ES512 | ECDSA P-521 + SHA512 |
| PS256 | RSA-PSS + SHA256 |
| none | None |
Registered Payload Claims (RFC 7519)
RFC 7519 defines seven reserved claim names with well-known meanings. Using these consistently allows JWT libraries and services to interoperate without custom configuration.
| Claim | Key |
|---|---|
| Issuer | iss |
| Subject | sub |
| Audience | aud |
| Expiration | exp |
| Not Before | nbf |
| Issued At | iat |
| JWT ID | jti |
How the Signature Works
The signature binds the header and payload together. For an HS256 token, the server computes:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
For RS256 and ES256, the private key signs the concatenated header and payload; the public key can verify the signature without knowing the private key. This is the asymmetric model used by most public identity providers (Google, Auth0, AWS Cognito).
Important: changing even one character in the header or payload produces a completely different signature, making the token invalid. The payload is not protected from reading — only from modification.
JWT vs Session Tokens
Both mechanisms achieve authentication; the right choice depends on your infrastructure and revocation requirements.
| Aspect | JWT | Session Token |
|---|---|---|
| Storage | Client-side (cookie or localStorage) | Server-side (Redis, database) |
| Server lookup | None — payload decoded from the token itself | Required — session ID looked up in store |
| Revocation | Hard — needs denylist or very short TTL | Easy — delete the session from the store |
| Token size | 200–800 bytes typically | Small opaque string (~32 bytes) |
| Scalability | Stateless; works across all servers without shared state | Requires a shared session store across servers |
| Secret rotation | Invalidates all existing tokens immediately | No impact on active sessions |
Common Security Pitfalls
alg:none Attack
An attacker strips the signature and sets alg to "none". A misconfigured library that accepts the none algorithm will validate any payload without checking a signature. Always explicitly allowlist the algorithms your server accepts — never trust the alg value blindly.
Algorithm Confusion (RS256 → HS256)
Some libraries that verify RS256 tokens can be tricked into accepting an HS256 token signed with the public key as the HMAC secret. Because the public key is public, an attacker can forge tokens. Always lock the expected algorithm server-side — do not let the token header choose it.
Sensitive Data in Payload
The payload is Base64URL-encoded, not encrypted. Anyone who obtains the token can decode it immediately — no key required. Never store passwords, credit card numbers, PII, or other secrets in JWT claims. Use encrypted JWTs (JWE) if the payload must be confidential.
Frequently Asked Questions
Can I decode any JWT without the secret key?
Yes. The header and payload are simply Base64URL-encoded JSON — anyone can decode them using any Base64 decoder. The secret key (or private key) is only needed to verify the signature, not to read the payload. This is why you must never put sensitive information in a JWT payload unless you use JWE (JSON Web Encryption).
What is the difference between JWT expiry and session expiry?
JWT expiry (the exp claim) is baked into the token itself and enforced by the verifier. Once a JWT is signed, its expiry cannot be changed without issuing a new token. Session expiry is controlled entirely server-side — a session can be extended, shortened, or invalidated at any time by updating the session store, regardless of when the original session was created.
Is it safe to store JWTs in localStorage?
localStorage is accessible to any JavaScript running on the page, making it vulnerable to XSS attacks. If an attacker injects a script, they can steal all stored tokens. The safer alternative is an httpOnly, Secure, SameSite=Strict cookie, which is inaccessible to JavaScript. For high-security applications, combine short-lived access tokens with a server-side refresh token rotation strategy.
What does "Bearer" mean in the Authorization header?
Bearer is a token type defined in RFC 6750. The Authorization: Bearer <token> header tells the server that the request is authenticated by the possession of the token itself — whoever bears the token is granted access. No additional proof of identity (such as a client certificate) is required, which is why keeping JWTs confidential and short-lived is critical.
How do I refresh a JWT without re-logging in?
The standard approach is a refresh token flow. When the short-lived access token (JWT) expires, the client sends a long-lived, opaque refresh token to a dedicated /refresh endpoint. The server validates the refresh token (often from a secure store), issues a new access JWT, and optionally rotates the refresh token. Refresh tokens should be stored in httpOnly cookies and rotated on each use to detect theft.
What is the maximum size of a JWT?
There is no hard limit defined in the JWT specification (RFC 7519), but practical limits apply. HTTP headers have a typical limit of 4–8 KB depending on the server. Cookies have a 4 KB limit per domain. A typical HS256 JWT with a few claims is 200–500 bytes. RS256 tokens are larger due to the RSA signature (~342 bytes of Base64 alone). Keep payloads small — store only what is needed for authorization decisions, not full user profiles.
Further Reading
Standards & References
Related Tools
- Base64 Encoder / Decoder — encode and decode individual Base64URL segments
- URL Encoder / Decoder — percent-encode tokens for use in query strings
- Unix Timestamp Converter — convert exp, nbf, and iat values to readable dates
- SHA-256 Hash Generator — explore the hash function used in RS256 and ES256