JSON Web Token (JWT) Decoder: Inspect JWT Content and Claims

· 12 min read

Table of Contents

Understanding JSON Web Tokens

JSON Web Tokens (JWTs) are compact, self-contained tokens used to securely transmit information between parties as a JSON object. They've become the de facto standard for authentication and information exchange in modern web applications, mobile apps, and microservices architectures.

Unlike traditional session-based authentication where user data is stored on the server, JWTs embed the data directly within the token itself. This fundamental difference makes JWTs ideal for stateless operations—the server doesn't need to maintain session storage or query a database to verify user identity on every request.

Think of a JWT like a digital passport. Just as a passport contains your identity information and is cryptographically secured with holograms and watermarks, a JWT contains claims about a user and is cryptographically signed to prevent tampering. When you present your passport at border control, officials can verify its authenticity without calling your home country—similarly, services can verify JWTs without contacting the issuing server.

Pro tip: JWTs are particularly useful in distributed systems and microservices architectures where maintaining centralized session state would create bottlenecks. Each service can independently verify tokens without cross-service communication.

Common scenarios where JWTs shine include:

The Three-Part Structure of JWTs

Every JWT consists of three distinct parts separated by periods (dots). Each part serves a specific purpose in the token's functionality and security model. When you see a JWT, it looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Let's break down each component:

Header

The header typically consists of two parts: the token type (which is JWT) and the signing algorithm being used, such as HMAC SHA256 or RSA. This information tells the receiving party how to process and verify the token.

A decoded header looks like this:

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

Payload

The payload contains the claims—statements about an entity (typically the user) and additional metadata. Claims are categorized into three types:

Claim Type Description Examples
Registered Claims Predefined claims recommended by the JWT specification iss, exp, sub, aud
Public Claims Custom claims defined by those using JWTs, should be collision-resistant name, email, role
Private Claims Custom claims agreed upon between parties department, permissions

A typical payload might look like:

{
  "sub": "1234567890",
  "name": "John Doe",
  "email": "[email protected]",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}

Signature

The signature is the cryptographic seal that ensures the token hasn't been tampered with. It's created by taking the encoded header, encoded payload, a secret key, and applying the algorithm specified in the header.

For example, if using HMAC SHA256, the signature is created like this:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

The signature allows the recipient to verify that the sender of the JWT is who it says it is and that the message wasn't changed along the way.

Why Use a JSON Web Token Decoder?

While JWTs are designed to be machine-readable, developers frequently need to inspect their contents during development, debugging, and security auditing. A JWT decoder transforms the Base64-encoded strings into human-readable JSON, making it easy to understand what information the token contains.

Here are the primary reasons developers use JWT decoders:

Development and Debugging

When building authentication systems, you need to verify that your tokens contain the correct claims and are properly formatted. A decoder lets you quickly inspect tokens without writing custom code or using command-line tools.

For instance, if users report authentication issues, you can decode their JWT to check if the exp (expiration) claim has passed or if required claims are missing.

Security Auditing

Security teams use JWT decoders to analyze tokens for potential vulnerabilities. They can check for:

Integration Testing

When integrating with third-party APIs that use JWT authentication, decoding tokens helps you understand the expected format and claims structure. This is especially useful when documentation is incomplete or outdated.

Learning and Education

For developers new to JWT, a decoder provides immediate visual feedback on how the three-part structure works and how changes to the payload affect the final token.

Quick tip: Never paste production JWTs containing real user data into online decoders. Use our JWT Decoder tool which processes tokens entirely in your browser without sending data to any server.

Step-by-Step Decoding Process

Decoding a JWT is straightforward once you understand the process. Here's how it works under the hood:

Step 1: Split the Token

First, split the JWT string at the period characters to separate the three parts:

const parts = token.split('.');
const header = parts[0];
const payload = parts[1];
const signature = parts[2];

Step 2: Base64 Decode

Each part is Base64URL encoded (a URL-safe variant of Base64). Decode the header and payload to get the JSON strings:

const decodedHeader = atob(header);
const decodedPayload = atob(payload);

Step 3: Parse JSON

Parse the decoded strings as JSON objects:

const headerObj = JSON.parse(decodedHeader);
const payloadObj = JSON.parse(decodedPayload);

Step 4: Inspect the Contents

Now you can examine the claims and metadata. Check for standard claims like:

Using our JWT Decoder, this entire process happens instantly in your browser. Simply paste your token and see the decoded header and payload immediately.

Validating the Token's Signature

Decoding a JWT is only half the story—validation is where security happens. Anyone can decode a JWT since it's just Base64-encoded JSON, but only parties with the correct secret or public key can verify the signature.

Why Signature Validation Matters

The signature ensures two critical security properties:

  1. Integrity: The token hasn't been modified since it was signed
  2. Authenticity: The token was created by a trusted party who possesses the secret key

Without signature validation, an attacker could decode a JWT, change the payload (perhaps elevating their privileges from "user" to "admin"), re-encode it, and use the modified token. The signature prevents this attack.

Validation Process

To validate a JWT signature, you need:

The validation process recreates the signature using the header and payload from the token, then compares it to the signature included in the token. If they match, the token is valid.

Pro tip: Always validate JWTs on the server side, never trust client-side validation alone. Attackers can bypass client-side checks, but they can't forge a valid signature without the secret key.

Common Signing Algorithms

Algorithm Type Key Type Use Case
HS256 HMAC with SHA-256 Symmetric (shared secret) Simple applications, same party creates and verifies
RS256 RSA with SHA-256 Asymmetric (public/private key pair) Distributed systems, multiple verifiers
ES256 ECDSA with SHA-256 Asymmetric (elliptic curve) Performance-critical applications, smaller signatures
none No signature None Never use in production!

Additional Validation Checks

Beyond signature verification, always validate:

Security Considerations and Best Practices

JWTs are powerful but require careful handling to maintain security. Here are essential best practices every developer should follow:

Never Store Sensitive Data in JWTs

Remember: JWTs are encoded, not encrypted. Anyone can decode them and read the payload. Never include:

Instead, store only non-sensitive identifiers and use those to look up sensitive data from a secure database when needed.

Use Strong Secrets and Key Management

For HMAC algorithms, use cryptographically random secrets at least 256 bits long. Store secrets securely using environment variables or dedicated secret management services like AWS Secrets Manager or HashiCorp Vault.

Never hardcode secrets in your source code or commit them to version control.

Set Appropriate Expiration Times

Short-lived tokens reduce the window of opportunity for attackers. Consider:

Implement refresh token rotation for enhanced security—issue a new refresh token each time one is used and invalidate the old one.

Implement Token Revocation

While JWTs are stateless, you still need a way to revoke compromised tokens. Common approaches include:

Validate Algorithm Headers

Always explicitly specify which algorithms your application accepts. Reject tokens using unexpected algorithms to prevent algorithm confusion attacks.

// Good: Explicitly specify allowed algorithms
jwt.verify(token, secret, { algorithms: ['RS256'] });

// Bad: Accept any algorithm
jwt.verify(token, secret);

Pro tip: Use our Password Generator to create strong secrets for HMAC signing, and our Hash Generator to create token IDs for revocation tracking.

Common JWT Issues and Solutions

Even experienced developers encounter JWT-related problems. Here are the most common issues and how to resolve them:

Issue 1: "Invalid Signature" Errors

Symptoms: Token validation fails with signature mismatch errors.

Common Causes:

Solutions:

Issue 2: Token Expired

Symptoms: Authentication fails with "token expired" or "exp claim validation failed" messages.

Common Causes:

Solutions:

Issue 3: Token Too Large

Symptoms: HTTP headers exceed size limits, cookies too large, or performance degradation.

Common Causes:

Solutions:

Issue 4: CORS Errors with JWT Authentication

Symptoms: Browser blocks requests with JWT in Authorization header due to CORS policy.

Solutions:

Issue 5: XSS and Token Storage Vulnerabilities

Symptoms: Tokens stolen through cross-site scripting attacks.

Solutions:

JWT vs. Traditional Session Authentication

Understanding when to use JWTs versus traditional sessions is crucial for building secure, scalable applications. Each approach has distinct advantages and trade-offs.

Traditional Session Authentication

In session-based authentication, the server creates a session after successful login and stores session data (user ID, permissions, etc.) in server memory or a database. The client receives a session ID, typically stored in a cookie.

Advantages:

Disadvantages:

JWT Authentication

With JWTs, all necessary information is contained in the token itself. The server validates the signature but doesn't need to store session data.

Advantages:

Disadvantages:

When to Use Each Approach

Use JWTs when:

Use sessions when:

Hybrid approach: Many modern applications use both—short-lived JWTs for API access and longer-lived refresh tokens stored as httpOnly cookies, combining the benefits of both approaches.

Real-World Use Cases and Examples

Let's explore practical scenarios where JWTs solve real authentication and authorization challenges.

Example 1: Mobile App Authentication

A fitness tracking app needs to authenticate users and allow them to sync data across devices without maintaining server sessions.

Implementation:

  1. User logs in with credentials
  2. Server validates credentials and issues a JWT containing user ID and subscription tier
  3. Mobile app stores JWT securely in device keychain
  4. Each API request includes JWT in Authorization header
  5. Server validates signature and extracts user ID from token
  6. Token expires after 7 days, requiring re-authentication

Sample JWT payload:

{
  "sub": "user_12345",
  "email": "[email protected]",
  "subscription": "premium",
  "iat": 1711900800,
  "exp": 1712505600
}

Example 2: Microservices Authorization

An e-commerce platform with separate services for users, products, orders, and payments needs to authorize requests across services.

Implementation:

  1. API gateway authenticates user and issues JWT with permissions
  2. JWT includes user role and specific permissions
  3. Each microservice validates JWT signature independently
  4. Services make authorization decisions based on claims
  5. No inter-service communication needed for authentication

Sample JWT payload:

{
  "sub