← Back to Blog
🔐
Dev Tools

JWT Decoder: Understanding JSON Web Tokens and How They Work

JSON Web Tokens, commonly written as JWT and pronounced jot, are a compact and self-contained way of representing claims between two parties. They are used extensively in web authentication and authorization, particularly in APIs and single-page applications where the server needs to verify who is making a request without maintaining session state on the server side.

The appeal of JWTs is that they are stateless. The server does not need to store session data or look up a session ID in a database to validate a request. All the information needed to verify the token and identify the user is contained within the token itself. The server only needs the secret key or public key to verify the token's signature.

The structure of a JWT

A JWT consists of three Base64URL-encoded parts separated by dots. The three parts are the header, the payload and the signature. An example token looks like a long string of characters with two dots dividing it into three segments. Each segment can be decoded independently to read its contents.

The header contains the token type, which is JWT, and the algorithm used to sign the token. Common algorithms include HS256, which uses HMAC with SHA-256 and a shared secret, and RS256, which uses RSA with SHA-256 and a public/private key pair. The algorithm specified in the header tells the receiving party how to verify the signature.

The payload contains the claims. Claims are statements about an entity, typically the user, and additional data. Standard claims include the subject (the user identifier), the issuer (who created the token), the audience (who the token is intended for), the expiration time, and the issued-at time. Custom claims can include any additional information the application needs, such as the user's role, permissions, or other attributes.

The signature is produced by encoding the header and payload with Base64URL, concatenating them with a dot, and then signing the result using the algorithm and key specified in the header. The signature prevents tampering with the token contents. Changing any character in the header or payload invalidates the signature, so any modification is detectable by the verifying party.

What JWTs do not do

JWTs are signed, not encrypted. The payload is Base64URL encoded, which is an encoding not an encryption. Anyone who has the token can decode the header and payload and read their contents. This is by design because the purpose of the signature is to verify authenticity and integrity, not to protect confidentiality.

Do not put sensitive information like passwords, credit card numbers or personal identification numbers in a JWT payload. The information is readable by anyone who intercepts the token. If you need to include sensitive data in a JWT that travels over public networks, use JWE, JSON Web Encryption, instead of a plain JWT.

JWTs cannot be revoked without additional infrastructure. Because the server does not maintain state, a valid token signed with the correct key is accepted until it expires, even if the user has since logged out or had their account suspended. Applications that need immediate revocation capability typically maintain a token blacklist or use short expiration times combined with refresh token rotation.

Common JWT authentication flows

In a typical web application using JWT authentication, the user submits their credentials to the login endpoint. The server verifies the credentials, creates a JWT containing the user's identifier and any relevant claims, signs it with the server's secret key, and returns it to the client. The client stores the token, typically in memory or local storage, and includes it in the Authorization header of subsequent requests as a Bearer token.

The server receiving a request with a JWT in the Authorization header extracts the token, verifies the signature using its secret or public key, checks that the token has not expired, and extracts the claims from the payload to identify the user and their permissions. No database lookup is needed for the verification itself, only for any application data the handler needs afterward.

Access tokens typically have short expiration times, often 15 minutes to an hour, to limit the window of exposure if a token is stolen. Refresh tokens with longer expiration times are used to obtain new access tokens without requiring the user to log in again. The refresh token is stored more securely, typically in an httpOnly cookie, while the access token is used directly in API requests.

Debugging JWT issues

When JWT authentication fails, the error is often in the claims rather than the signature. An expired token produces a different error from an invalid signature, which produces a different error from a token with an incorrect audience claim. Decoding the token and examining the payload reveals the expiration time, the issuer, the audience and any custom claims, which makes it straightforward to identify which claim is causing the rejection.

Timezone issues frequently cause unexpected token expiration. JWT timestamps are Unix timestamps, which are UTC by default. If the server generating the token and the server validating it have different system times, or if either system's clock is significantly wrong, tokens may appear expired immediately or never expire correctly. Checking the iat and exp claims in a decoded token against the current UTC time identifies this class of problem quickly.

  1. Open the JWT Decoder below.
  2. Paste your JWT token into the input field.
  3. See the header, payload and signature decoded and formatted.
  4. Check the claims including expiration time and user details.
💡 When debugging a JWT authentication problem, always start by decoding the token and checking the exp claim against the current UTC time. Expired tokens are the most common cause of unexpected authentication failures.

Decode and inspect any JWT token instantly to debug authentication issues.

JWT security considerations

The algorithm confusion vulnerability is one of the more subtle JWT security issues. Some early JWT libraries accepted the algorithm specified in the token header as the algorithm to use for verification. An attacker could change the header algorithm from RS256 to HS256, which is a different verification method, and then sign the modified token using the public key as the HMAC secret. Libraries that do not explicitly specify which algorithm to accept are vulnerable to this attack. Always configure the verifying library to only accept the expected algorithm rather than trusting the algorithm field in the token header.

The none algorithm is an explicit vulnerability in some implementations. The JWT specification allows an algorithm value of none to indicate an unsigned token. Libraries that accept this value will pass any token claiming to use no algorithm regardless of content, essentially disabling signature verification entirely. Well-maintained libraries explicitly reject the none algorithm, but it is worth verifying that your chosen library does not accept it.

Storing JWTs securely on the client

JavaScript-accessible storage like localStorage and sessionStorage is vulnerable to cross-site scripting attacks. An XSS attack that can execute JavaScript in the context of your application can read tokens stored in these locations and use them to impersonate the user. HttpOnly cookies, which cannot be accessed by JavaScript, provide better protection against token theft via XSS.

The trade-off is that HttpOnly cookies require CSRF protection because any request to your domain automatically includes the cookie, making cross-site request forgery attacks possible if you only rely on the cookie for authentication. Combining HttpOnly cookies with a CSRF token mechanism provides strong protection against both XSS token theft and CSRF attacks.

Alternatives to JWTs

JWTs are one approach to stateless authentication but not the only one. Opaque tokens, which are random strings that must be looked up in a database or cache to determine their associated user and claims, provide the ability to revoke tokens instantly by deleting the database record. The trade-off is the database round-trip on every authenticated request, which adds latency and a dependency on the token store.

Session cookies backed by server-side storage are the traditional approach and remain appropriate for many applications. They are stateful, require server-side storage, and support immediate revocation. For applications that do not need the distributed verification properties of JWTs, the simpler mental model and better revocation support of server-side sessions is worth considering against the stateless advantages of JWTs.

Refresh token rotation is the practice of issuing a new refresh token whenever a refresh token is used to obtain a new access token. The old refresh token is invalidated immediately after use. If a stolen refresh token is used by an attacker, the legitimate user's next token refresh will fail because their refresh token has already been rotated by the attacker's use. This failure signals a possible token theft and allows the system to invalidate the session, requiring the user to authenticate again.