Skip to content
ToolMint
Back to blog

How to Decode a JWT Token Online — Step-by-Step Guide

April 12, 202611 min read

What Is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe string used to transmit claims between two parties — typically a client and a server. You encounter them constantly in modern web development: they are the access tokens your app stores in localStorage, the bearer tokens in Authorization headers, the session credentials returned after OAuth login.

A JWT looks like three chunks of text separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The three parts are:

  1. Header — algorithm and token type
  2. Payload — the actual claims (user ID, roles, expiry time, etc.)
  3. Signature — cryptographic proof that the header and payload have not been tampered with

Each part is Base64URL-encoded, which is why it looks like scrambled text. Decoding reveals the underlying JSON.

The Three Parts Explained

Header

The header specifies the signing algorithm and the token type. Decoded, it typically looks like:

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

alg is the algorithm used to sign the token. Common values:

  • HS256 — HMAC-SHA256. Uses a shared secret key. Common in server-to-server communication.
  • RS256 — RSA-SHA256. Uses a public/private key pair. Common in OAuth and OpenID Connect flows.
  • ES256 — ECDSA-SHA256. Elliptic curve. Compact signatures, used in modern auth systems.
  • none — No signature. If you see this in a production token, it is almost always a serious security problem.

Payload

The payload contains the claims — statements about the user or session. Decoded:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622,
  "iss": "https://auth.example.com",
  "aud": "https://api.example.com",
  "roles": ["admin", "editor"]
}

Signature

The signature is not readable as JSON — it is a cryptographic hash generated by taking the encoded header and payload, running them through the specified algorithm with a secret key, and Base64URL-encoding the result. You cannot reconstruct the secret key from the signature, and you cannot verify the signature without the key.

Decoding a JWT reads the header and payload. It does not verify the signature. Verification requires the secret key (for HS256) or the public key (for RS256/ES256).

When You Need to Decode a JWT

Debugging Authentication Issues

The most common reason developers decode JWTs is to diagnose auth bugs. When a request returns 401 Unauthorized or 403 Forbidden and you are not sure why, decoding the token tells you immediately what claims the server actually received. You might discover:

  • The token has already expired (exp is in the past)
  • The subject (sub) is wrong — the wrong user ID
  • Required roles or scopes are missing from the payload
  • The audience (aud) does not match what the server expects
  • The issuer (iss) does not match the configured allowed issuer

Without decoding the token, diagnosing these issues requires server-side logging, which is not always accessible.

Checking Token Expiry

Tokens issued by identity providers typically expire in 15 minutes to 24 hours. When you are debugging a workflow that fails intermittently, the first thing to check is whether the token expired mid-session. Decoding the token shows you the exp claim as a Unix timestamp, which you can compare to the current time.

Reading User Claims in Frontend Code

Sometimes you need to read claims on the frontend — for example, to get the user's name for a greeting, their role for conditional UI rendering, or their ID for an analytics event. Decoding the payload in-browser is standard practice, because the payload is not encrypted (only signed). Reading it does not require any API call.

Understanding Third-Party Token Structures

When integrating with a new OAuth provider, SSO system, or API that uses JWTs, decoding a sample token helps you understand what claims it includes and how they map to your application's needs. This is faster than reading documentation that may be incomplete or out of date.

Verifying Token Contents During Development

During local development, you often need to verify that your auth system is generating tokens with the right claims. Decoding a fresh token lets you confirm the payload without writing a separate test or adding debug logging to the server.

How ToolMint's JWT Decoder Works

ToolMint's JWT decoder is built into the Text Studio and runs entirely in your browser. The token you paste is processed using JavaScript's atob() function and standard JSON parsing — it never leaves your device, never touches a ToolMint server, and is not logged anywhere.

This is not a marketing claim — it is the technical reality. Base64 decoding is trivial to do client-side, and there is no reason to transmit the token to a server. When you use an online JWT decoder, the only thing that should happen is local string manipulation in your browser tab.

This matters because JWTs are credentials. A valid, unexpired JWT for a production system is effectively a set of keys to that system. Pasting it into an untrusted third-party tool creates a real risk of credential theft. ToolMint's decoder does not transmit your token anywhere.

Step-by-Step: How to Decode a JWT

Step 1: Open the JWT Decoder

Go to toolmint.app/studio/text and select the JWT Decoder tool.

Step 2: Paste Your Token

Paste the full JWT string into the input field. The token should look like three dot-separated chunks of characters. Make sure you include all three parts — a common mistake is accidentally copying only the first two parts.

Step 3: Read the Decoded Output

The tool displays three sections:

  • Header — the algorithm and token type in formatted JSON
  • Payload — all claims in formatted JSON with proper indentation
  • Signature — the raw signature string (not decoded to a key)

Each section is syntax-highlighted for readability. You can copy individual sections using the copy buttons.

Step 4: Interpret the Claims

Use the common fields reference below to understand what each claim means and whether the values look correct for your use case.

Common JWT Claims

These are the standard registered claims defined by the JWT specification (RFC 7519). Many tokens also include custom claims specific to the application.

Claim Full Name Type Description
sub Subject String Unique identifier for the user or entity the token represents. Often a user ID.
iss Issuer String URL or identifier of the system that issued the token.
aud Audience String or Array Who the token is intended for. Servers validate that their identifier matches.
exp Expiration Time Unix timestamp When the token expires. The server should reject tokens where exp < current time.
iat Issued At Unix timestamp When the token was issued.
nbf Not Before Unix timestamp The token should not be accepted before this time.
jti JWT ID String A unique identifier for this specific token. Used to prevent replay attacks.
name Name String User's full name. Non-standard but extremely common.
email Email String User's email address.
roles Roles Array User's permission roles. Non-standard, varies by implementation.
scope Scope String OAuth scopes granted. Space-separated.

Reading Unix Timestamps

exp and iat values are Unix timestamps — seconds elapsed since January 1, 1970 (UTC). 1716239022 is not a human-readable date. To convert:

  • In a browser console: new Date(1716239022 * 1000) — multiplying by 1000 converts to milliseconds
  • In Python: datetime.fromtimestamp(1716239022)
  • On ToolMint's Unix timestamp converter: paste the value and see the human-readable equivalent

ToolMint's JWT decoder converts these timestamps to readable dates automatically in the decoded output.

Security Warnings

Never Share Production JWTs

A JWT is a credential. If your token grants access to a production system and has not expired, sharing it with anyone — including pasting it into a third-party tool — is equivalent to sharing a password. Anyone who obtains a valid, unexpired JWT can authenticate as you.

If you suspect a token has been compromised, invalidate it immediately through your auth provider's token revocation mechanism.

Decoding Is Not the Same as Verifying

Decoding reads the payload. It does not check whether the token is valid, whether the signature is authentic, or whether the token has been tampered with. Only your server can verify a JWT's signature using the secret or public key.

This means you should never use client-side decoded claims for security decisions. If a decoded token claims "roles": ["admin"], that claim is only trustworthy after server-side signature verification. A modified token with a fake payload will decode perfectly but will fail server-side verification.

Be Careful With Test Tokens

If you are testing with real-user JWTs from a production system (even in a debugging context), be aware that those tokens may grant real access. Use test users or short-lived tokens when debugging auth flows.

Tokens in URLs Are Risky

JWTs should be transmitted in the Authorization: Bearer <token> header, not in query strings. Tokens in URLs appear in server logs, browser history, referrer headers, and analytics tools — all of which may persist long after the token has expired.

If you see JWTs being passed in URLs in your system, that is a security design issue worth flagging.

Tips for Working With JWTs

  • Check exp first. When debugging an auth issue, always check the expiry time before diving into other claims. A surprising number of auth bugs are simply expired tokens.
  • Match aud and iss against your server config. Mismatches between the token's audience and the server's expected audience cause silent rejections that are hard to diagnose without decoding the token.
  • Use short expiry times in production. Tokens that expire in 15–60 minutes limit the damage of a compromised token. Use refresh tokens for long-lived sessions.
  • Do not put sensitive data in JWT payloads. The payload is Base64-encoded, not encrypted. Anyone who obtains the token can read the claims. Do not include passwords, payment details, or secrets in the payload.
  • Use the jti claim for revocation. If your system needs to revoke tokens before they expire (on logout, password change, or role change), store used jti values in a denylist.

FAQ

Does ToolMint send my JWT to its servers?

No. The JWT decoder runs entirely in your browser. Your token is processed using local JavaScript and is never transmitted to ToolMint's servers or any third party.

Can ToolMint verify my JWT signature?

No. Signature verification requires the secret key (for HS256) or the public key (for RS256/ES256), which only your server has. The decoder reads and displays the header and payload but cannot validate that the signature is authentic.

The token looks valid but my app is returning 401. What should I check?

Decode the token and verify: (1) exp is in the future, (2) iss matches what your server expects, (3) aud matches your server's identifier, (4) required roles or scope values are present. If all claims look correct, the issue may be server-side: a misconfigured signing key, an expired server certificate, or a token blocklist that includes this token's jti.

What does it mean if alg is "none"?

A token with "alg": "none" has no cryptographic signature — it is unsigned. Any server that accepts unsigned tokens can be tricked by attackers who craft arbitrary payloads. If you see this in a production token, it is a critical security vulnerability that should be fixed immediately.

How do I decode a JWT in code?

In JavaScript/Node.js: JSON.parse(atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))). The replace calls handle the URL-safe Base64 encoding. In Python: import jwt; jwt.decode(token, options={"verify_signature": False}). Most languages have a JWT library that simplifies this.