JWT Decoder
Decode JWT (JSON Web Token) in your browser and visualize the header, payload, and signature.iat / exp / nbf are automatically converted to human-readable dates.
Header
Payload
Signature
* Signature verification requires a secret or public key, so this tool only decodes.
About the JWT structure
A JWT is a string consisting of header.payload.signature three parts joined with dots (.). The header and payload are Base64URL-encoded JSON, and the signature is generated using the algorithm specified in the header (e.g., HS256 / RS256).
Key claims: iss (issuer), sub (subject), aud (audience), exp (expiration), nbf (not before), iat (issued at), jti (JWT ID)
📖 Where people get stuck
Splits a JWT into its header, payload and signature and converts time claims such as exp and iat into readable dates. Everything runs in the browser, and the signature is not verified, since that needs a key. The point to take away is that being able to decode it means anyone can read its contents — a JWT payload is not encrypted; it is merely Base64URL encoded.
| Case | What happens | What to do |
|---|---|---|
| Putting secrets into the payload | Base64URL is an encoding, not encryption — as this page demonstrates, anyone without a key can read the contents. Yet the belief that a signature makes it safe is stubborn, and you see designs that put personal data, the internal permission structure, in-house identifiers, and sometimes an email address and a date of birth, all into the payload. A JWT sits in localStorage or a cookie, appears in logs, and sometimes travels in a URL — treating its contents as public information is the accurate stance. |
Put only an identifier in the payload and look the rest up on the server — a user id and a role name, not a name, an email address or an address. If you need encryption, JWE (JSON Web Encryption) is a separate specification for it, but first ask whether it needs to be in the JWT at all: usually what you need is who this is, and what they are can stay on the server. The test is simple — would you mind this value appearing in plain text in an access log? If not, it can go in; if you would, it cannot. |
| Trusting the contents after merely decoding | Without verifying the signature, a JWT is just a string the user can rewrite at will. Code that decodes it, reads role: "admin" and uses that for authorisation accepts a token in which the attacker wrote that value themselves. Two failures are historically famous. One is the alg: "none" attack: rewrite the header algorithm to none, leave the signature empty, and some implementations accepted it without complaint. The other is confusing HS256 with RS256, where getting the verifier to use the public key as an HMAC secret lets an attacker forge a valid signature from public information alone. |
Always verify with the library verification function, and pin the permitted algorithms explicitly — jwt.verify(token, key, { algorithms: ["RS256"] }). Omit that argument and some implementations will trust the alg in the header, which is to let a value the attacker controls decide how verification happens. Never use a decode-only function — anything named like jwt.decode — for an authorisation decision: the names are similar enough to be confused, but it performs no verification and exists only for debugging output. Before writing the code, check which function in your library verifies and which merely decodes. |
| The token still works after logging out | Being stateless is the design advantage of a JWT and simultaneously its greatest constraint. The server does not store the token, so there is no way to invalidate an individual one after issuing it. Logging out really means discarding the token on the client, and anyone who copied it can keep using it until it expires. For the same reason, revoking a permission leaves the old permission written into tokens already issued. That is why access for someone who has left can persist for an hour after you thought you had cut it off. | Use a short expiry paired with a refresh token — an access token of about fifteen minutes, renewed with a refresh token that the server does track. With that arrangement, revoking the refresh token cuts access within fifteen minutes at most. If immediate revocation is a requirement, you need a blocklist — storing the ids of revoked tokens and checking against it during verification — but that means holding state, which gives up part of the reason for using a JWT. That is the decision point: if you genuinely need immediate revocation, a session id with a server-side session is simpler and more reliable. JWTs suit authentication that spans multiple services, or where you want verification itself to be distributed. |
The time claims are in seconds. exp, iat and nbf are all Unix seconds, and putting milliseconds in gives an expiry fifty thousand years out — an effectively permanent token. Because JavaScript Date.now() returns milliseconds, writing Date.now() + 3600000 and dropping it into exp is a very common mistake; the correct form is Math.floor(Date.now() / 1000) + 3600. If the decoded date lands far in the future, suspect exactly this — showing the claims as readable dates is precisely what lets you catch it by eye. Second, allow a leeway of a few tens of seconds when validating nbf and exp, to absorb clock skew between servers; the major libraries all have that option. Finally, an operational warning: do not paste a live production token into an online JWT decoder — it is a credential, and if it lands in the logs of whatever server you pasted it into, someone else can impersonate you with it. This page runs entirely in your browser, but make a habit of confirming that in the Network tab of your developer tools.
📖 How to Use
-
1
Copy your JWTGet the JWT string from your API response or Authorization header.
-
2
Paste into the inputPaste the JWT into the top textarea and decoding runs automatically.
-
3
Inspect header & payloadView algorithm (alg), issuer (iss), expiration (exp) and other claims visually.
❓ Frequently Asked Questions
What is a JWT?
Can this tool verify the signature?
Is the JWT sent to any server?
What if exp is expired?
🐛 Found a bug or issue with this tool?
Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.
Thanks for your report!
Your report has been delivered to the operator and will be used to improve the tool.