JWT Decoder

JWT Decoder
Encoded token
Decoded
Header, payload, and signature appear here as you type.
Waiting for a token
100% client-side. Your token is never sent anywhere.

This free JWT decoder lets you paste any JSON Web Token and instantly read its header, payload, and signature in a clean, color-coded view. It runs entirely in your browser, decodes time claims like expiry into readable dates, and flags expired tokens automatically. Below the tool you will find a complete, practical guide to what JWTs are, how they work, how to read every standard claim, the security mistakes that get developers into trouble, and answers to the questions people ask most often.

What is a JWT?

A JSON Web Token, almost always shortened to JWT and pronounced “jot,” is a compact and self-contained way to transmit information between two parties as a digitally signed JSON object. It is defined by the open standard RFC 7519 and has become one of the most widely used mechanisms for authentication and authorization on the modern web. When you log into a web application and it keeps you signed in across page loads and API calls, there is a good chance a JWT is doing the work behind the scenes.

The word “self-contained” is the key idea. A JWT carries its own data. Instead of the server storing a session record and handing you an opaque ID that points back to it, the server can put the actual information, such as who you are and what you are allowed to do, directly inside the token, then sign it so nobody can tamper with it. The server hands that token to the client, the client sends it back on every request, and the server only needs to verify the signature rather than look anything up in a database. This statelessness is what makes JWTs so popular for distributed systems, microservices, and APIs.

The three parts of a JWT

Every JWT is a single string made of three sections separated by dots, in the form header.payload.signature. Each of the first two sections is a JSON object that has been Base64URL-encoded, and the third is a cryptographic signature. If you look at a raw token you will see something like this, with the three parts visible between the dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The decoder above splits the token on those dots, decodes the first two sections from Base64URL back into readable JSON, and displays the third as the raw signature. Let us look at each part in turn.

1. The header

The header is a small JSON object that describes the token itself. It almost always contains two fields. The first is alg, which names the algorithm used to sign the token, such as HS256 or RS256. The second is typ, the type, which is simply JWT. A typical header looks like this:

{
  "alg": "HS256",
  "typ": "JWT"
}

Sometimes you will see a kid field as well. That stands for “key ID” and tells the verifying server which key to use when a system rotates between multiple signing keys. The header is the first thing the decoder reads, and the algorithm it advertises is shown in the status bar of the tool.

2. The payload

The payload is where the interesting data lives. It is a JSON object containing what the standard calls “claims,” which are simply statements about an entity, usually the user, plus metadata about the token. A payload might look like this:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "exp": 1900000000
}

There are three categories of claims. Registered claims are a set of predefined, standardized names like iss, exp, and sub that you are encouraged to use for interoperability. Public claims are names you can define yourself but should register or namespace to avoid collisions. Private claims are custom names that two parties agree on privately, like admin or role in the example above. The decoder reads the entire payload and, for the standard time-based claims, converts the raw numbers into human-readable dates.

3. The signature

The signature is what makes a JWT trustworthy. It is created by taking the encoded header, the encoded payload, a secret or private key, and running them through the algorithm named in the header. The result is appended as the third part of the token. When a server receives the token back, it repeats the same calculation and checks that the signature matches. If even a single character of the header or payload has been changed, the signature will not match and the token is rejected.

This tool decodes and displays the signature, but it does not verify it. Verifying a signature requires the secret or public key, and a browser tool should never ask you to paste your signing secret into a web page. Verification belongs on your server.

What every standard claim means

The JWT standard defines a handful of registered claims that appear again and again. Knowing them by sight makes reading any token much faster. The decoder above surfaces the time-based ones as readable dates, but here is the full reference.

ClaimNameWhat it means
issIssuerWho created and signed the token, such as your auth server or an identity provider.
subSubjectWho or what the token is about, usually a unique user ID.
audAudienceThe intended recipient. A service should reject a token not meant for it.
expExpirationA Unix timestamp after which the token must not be accepted.
nbfNot beforeA Unix timestamp before which the token is not yet valid.
iatIssued atA Unix timestamp recording when the token was created.
jtiJWT IDA unique identifier for the token, useful for preventing replay.

The three timestamp claims, exp, nbf, and iat, are expressed as the number of seconds since January 1, 1970, the Unix epoch. They are not human friendly on their own, which is why the decoder converts them. When a token has expired, the tool shows an amber warning next to the expiry so you can see at a glance whether a token is still live.

How JWT authentication works in practice

Understanding the data is one thing; understanding the flow is another. A typical JWT authentication cycle looks like this.

  1. A user submits their username and password to a login endpoint.
  2. The server checks the credentials. If they are correct, it builds a payload containing the user’s ID and any relevant claims, signs it, and returns the resulting JWT to the client.
  3. The client stores the token, then attaches it to future requests, conventionally in an HTTP header that reads Authorization: Bearer .
  4. For each protected request, the server verifies the signature, checks the expiry and audience, and, if everything is valid, trusts the claims inside without needing a database lookup.
  5. When the token expires, the client either logs in again or uses a separate refresh token to obtain a new one.

The elegance here is that the server does not have to remember anything between requests. The token itself carries the proof. This is what people mean when they say JWTs enable “stateless” authentication, and it is why they scale so well across many servers that do not share a session store.

JWT signing algorithms: HS256 vs RS256

The algorithm in the header determines how the signature is produced and verified, and the choice has real consequences. The two you will encounter most often are HS256 and RS256.

HS256 is a symmetric algorithm. It uses a single shared secret for both signing and verifying. Whoever can verify a token can also create one, because they hold the same secret. This is simple and fast, and it is a fine choice when the same trusted party both issues and checks tokens.

RS256 is asymmetric. It uses a private key to sign and a separate public key to verify. The issuer keeps the private key secret, while anyone can be given the public key to verify tokens without being able to forge them. This is the right choice when many independent services need to verify tokens that only a central authority should be able to issue, which describes most single sign-on and third-party identity setups.

You may also see ES256, which is similar to RS256 but uses elliptic-curve cryptography for smaller keys and signatures, and none, which means the token is unsigned. The none algorithm exists in the specification but is dangerous, as explained below.

Common JWT security mistakes

JWTs are powerful but easy to misuse. Most real-world incidents trace back to a small set of recurring errors. Knowing them protects you whether you are building with tokens or reviewing someone else’s code.

Treating the payload as secret

This is the single most important thing to understand, and the reason this decoder works at all. A JWT is signed, not encrypted. The header and payload are merely Base64URL-encoded, which is encoding, not encryption. Anyone who gets hold of a token can decode and read everything in it, exactly as this tool does, with no key required. Never put passwords, full credit card numbers, or other secrets in a JWT payload. If you genuinely need the contents hidden, you need an encrypted variant such as JWE, not a plain signed JWT.

Accepting the “none” algorithm

An infamous vulnerability arises when a server trusts the algorithm field in the header without restriction. An attacker takes a valid token, changes the algorithm to none, strips the signature, and sends it back. A naive verifier sees “no signature required” and accepts the forged token. Always configure your library to accept only the specific algorithms you expect, and never let a client dictate the verification algorithm.

Not validating expiry or audience

Decoding a token is not the same as validating it. A token can be perfectly well-formed and still be expired, not yet valid, or intended for a completely different service. Servers must check exp, nbf where present, and aud on every request. Skipping these checks lets old or misdirected tokens through.

Storing tokens insecurely on the client

Where you keep a token in the browser matters. Storing it in localStorage makes it readable by any JavaScript on the page, which means a single cross-site scripting flaw can leak it. Storing it in an HttpOnly cookie keeps it out of reach of JavaScript but introduces other considerations around cross-site request forgery. There is no perfect answer, only trade-offs to weigh deliberately rather than by accident.

Tokens that never expire

A JWT that lasts forever is a liability, because once issued it cannot easily be revoked. The common pattern is to issue short-lived access tokens, often valid for minutes, alongside longer-lived refresh tokens that can be revoked server-side. This limits the damage if a token is stolen.

JWT vs traditional sessions

It is worth being clear about when a JWT is the right tool, because they are not always better than the older server-side session approach. With traditional sessions, the server stores session data and gives the client a meaningless ID. With JWTs, the data travels in the token and the server stores nothing.

AspectServer sessionsJWT
Server storageRequired for every sessionNone needed
Scaling across serversNeeds a shared storeNaturally stateless
Revoking access instantlyEasy, delete the sessionHard, token stays valid until expiry
Size sent per requestSmall IDLarger, the whole token

The headline trade-off is revocation versus scale. Sessions make it trivial to log someone out everywhere by deleting their record, but they require shared storage. JWTs scale effortlessly but cannot be un-issued before they expire. The short-access-token-plus-refresh-token pattern exists precisely to soften that downside.

How to use this JWT decoder

Using the tool above is straightforward. Paste your token into the left box, or click “Try a sample” to load an example token so you can see the output format. The decoder immediately splits the token, decodes the header and payload, and color-codes the JSON so keys, strings, numbers, and booleans are easy to distinguish. If the token is malformed, for example if it does not have the expected three parts, the tool tells you what is wrong instead of failing silently. Because everything happens in your browser, you can decode tokens that contain real data without it ever leaving your machine.

A practical workflow: when an API call is being rejected as unauthorized, paste the token your client is sending into the decoder and check the exp claim. A surprising share of “it works on my machine” authentication bugs turn out to be nothing more than an expired token or a clock that disagrees about the current time.

Reading a real token, claim by claim

Theory becomes much clearer with a concrete example. Suppose you decode a token and the payload looks like this:

{
  "iss": "https://auth.codezips.com",
  "sub": "user_8842",
  "aud": "codezips-api",
  "name": "Asha Patel",
  "role": "editor",
  "iat": 1716000000,
  "nbf": 1716000000,
  "exp": 1716003600,
  "jti": "f1c2-9a7e-44b1"
}

Reading it from top to bottom tells you a complete story. The iss field says this token was issued by your authentication server at auth.codezips.com, so a verifier should confirm it trusts that issuer. The sub identifies the user as user_8842, a stable internal ID rather than something that changes like an email address. The aud says the token is intended for the codezips-api service specifically, so a different service receiving this token should reject it even if the signature is valid.

The name and role are custom private claims. They let the API know who is acting and what they are permitted to do without a database lookup, which is the whole efficiency argument for JWTs. Be careful, though: because anyone can read these, the role claim is a convenience, not a security boundary on its own. The server must still enforce that an editor cannot perform admin actions; it should never simply trust the role and skip its own authorization checks.

The three timestamps tell you the token’s lifecycle. The iat and nbf are equal here, meaning the token became valid the moment it was issued. The exp is one hour later, so this is a short-lived access token. The decoder above turns all three into readable dates and warns you the instant the expiry has passed. Finally, jti is a unique ID for this specific token, which a server can record to detect if the same token is being replayed after it should have been retired.

Refresh tokens and revocation

The biggest practical weakness of JWTs is revocation. Because a signed token is valid until it expires no matter what, you cannot simply “delete” it the way you can delete a server session. If a token is stolen, it remains usable until the exp moment arrives. The standard answer to this problem is a two-token design.

The first token is the access token. It is a JWT, it carries the user’s claims, and it is deliberately short-lived, often valid for only five to fifteen minutes. The client sends it on every request. Because its lifetime is so short, a stolen access token is only useful for a brief window.

The second token is the refresh token. It lives longer, sometimes days or weeks, and its only job is to obtain new access tokens. Crucially, the refresh token is usually stored server-side or in a revocation list, so it can be cancelled at any time. When a user logs out or you detect suspicious activity, you invalidate the refresh token. The current access token might survive a few more minutes, but it cannot be renewed, so access ends quickly and cleanly.

This pattern gives you most of the scaling benefits of stateless JWTs while restoring the ability to cut off access, which pure long-lived JWTs lack. If you are designing an authentication system, reach for short access tokens plus revocable refresh tokens rather than issuing one long-lived token and hoping it is never compromised.

A useful rule of thumb: the access token answers “who are you and what can you do right now,” while the refresh token answers “are you still allowed to keep getting new access tokens.” Keeping those jobs separate is what makes revocation possible.

Frequently asked questions

Is it safe to decode a JWT online?

With this tool, yes, because decoding happens entirely in your browser and the token is never transmitted anywhere. As a general habit, be cautious with online tools that send tokens to a server, and never paste production secrets or signing keys into any web page.

Can a JWT be decoded without the secret key?

Yes. The header and payload are only Base64URL-encoded, not encrypted, so anyone can read them without any key. The secret key is needed only to verify or create the signature, not to read the contents. This is why you must never store sensitive data in a JWT payload.

What is the difference between decoding and verifying a JWT?

Decoding means reading the header and payload, which requires no key. Verifying means cryptographically confirming the signature is authentic and the token has not been tampered with or expired, which requires the secret or public key and should be done on a server.

Why is my JWT showing as expired?

The exp claim holds a Unix timestamp, and if that moment is in the past the token is expired. This tool converts exp to a readable date and flags expiry automatically. An expired token must be refreshed or the user must log in again.

Can I edit a JWT and re-sign it here?

No. This is a read-only decoder by design. Re-signing requires the secret or private key, which should never be entered into a browser tool. Generate and sign tokens in your backend using a trusted library.

What does the “alg” field tell me?

It names the signing algorithm, such as HS256 (a shared secret) or RS256 (a public/private key pair). The tool shows it in the status bar. On the server side you should always restrict which algorithms you accept rather than trusting whatever the token claims.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top