Understanding JWT Tokens: How to Decode and Verify JWTs

Published on December 28, 2024

JSON Web Tokens (JWTs) have become the standard for API authentication and authorization. They're used by major platforms like Google, Microsoft, and countless web applications. Understanding how JWTs work, how to decode them, and how to verify their authenticity is essential for modern web development.

This comprehensive guide will teach you everything about JWT tokens, from their structure to decoding and verification. You'll learn about JWT claims, expiration handling, security considerations, and best practices for working with JWTs in your applications.

Quick Start: Need to decode a JWT right now? Try our free JWT Decoder—it decodes header and payload, shows expiration status, and formats the JSON data for easy reading.

What is a JWT Token?

A JSON Web Token (JWT) is a compact, URL-safe token format used for securely transmitting information between parties. JWTs are self-contained, meaning they carry all necessary information within themselves, making them ideal for stateless authentication.

Key Characteristics of JWTs

  • Compact: JWTs are small and can be easily transmitted via URL, POST parameters, or HTTP headers.
  • Self-Contained: All necessary information is in the token itself, reducing database lookups.
  • Stateless: No server-side session storage required, making them scalable.
  • Signed: JWTs are signed to ensure integrity and authenticity.
  • Standardized: Based on RFC 7519, ensuring compatibility across platforms.

Common Use Cases

  • API Authentication: Authenticate API requests without storing sessions.
  • Single Sign-On (SSO): Share authentication across multiple applications.
  • Information Exchange: Securely transmit information between parties.
  • Authorization: Include user permissions and roles in the token.
  • Microservices: Authenticate requests between microservices.

JWT Structure

A JWT consists of three parts separated by dots (.): header.payload.signature

Example JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1. Header

The header typically consists of two parts: the token type (JWT) and the signing algorithm (e.g., HMAC SHA256 or RSA).

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

2. Payload

The payload contains the claims. Claims are statements about an entity (typically the user) and additional metadata.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622
}

3. Signature

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

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

How to Decode a JWT

Decoding a JWT is straightforward—it only requires base64 decoding. However, remember that decoding doesn't verify the signature. Anyone can decode a JWT, but only those with the secret key can verify it.

Using Our JWT Decoder Tool

  1. Paste Your JWT: Copy and paste your JWT token into the input field. You can include or exclude the "Bearer" prefix.
  2. Automatic Decoding: The tool automatically decodes the header and payload, displaying them as formatted JSON.
  3. View Claims: See all claims in the payload, including standard claims like 'exp', 'iat', 'sub', and custom claims.
  4. Check Expiration: The tool automatically checks if the token is expired and displays expiration status.
  5. Copy Decoded Data: Copy the decoded header or payload JSON for use in your code or documentation.

Decoding Programmatically

JavaScript:

function decodeJWT(token) {
  const parts = token.split('.');
  const header = JSON.parse(atob(parts[0]));
  const payload = JSON.parse(atob(parts[1]));
  return { header, payload };
}

Important: Decoding a JWT only reveals its contents—it doesn't verify authenticity. Always verify the signature before trusting JWT data in production applications.

Verifying JWT Signatures

Signature verification ensures that the JWT hasn't been tampered with and was issued by a trusted party. This requires the secret key (for HMAC algorithms) or public key (for RSA algorithms).

Why Verification Matters

  • Prevents Tampering: Verifies that the token hasn't been modified after issuance.
  • Ensures Authenticity: Confirms the token was issued by a trusted source.
  • Protects Data: Prevents attackers from creating fake tokens with modified claims.
  • Validates Integrity: Ensures the header and payload match the signature.

Verification Steps

  1. Extract Header and Payload: Decode the header and payload from the JWT.
  2. Check Algorithm: Verify the algorithm matches what you expect (prevent algorithm confusion attacks).
  3. Recreate Signature: Use the secret key and the same algorithm to recreate the signature.
  4. Compare Signatures: Compare the recreated signature with the signature in the JWT.
  5. Check Expiration: Verify the token hasn't expired by checking the 'exp' claim.
  6. Validate Claims: Check other claims like 'iss' (issuer), 'aud' (audience) if applicable.

Understanding JWT Claims

Claims are pieces of information asserted about a subject. JWTs include registered claims, public claims, and private claims.

Registered Claims

  • iss (Issuer): Identifies who issued the JWT.
  • sub (Subject): Identifies the subject of the JWT (usually the user ID).
  • aud (Audience): Identifies the recipients that the JWT is intended for.
  • exp (Expiration Time): Unix timestamp when the JWT expires.
  • nbf (Not Before): Unix timestamp before which the JWT must not be accepted.
  • iat (Issued At): Unix timestamp when the JWT was issued.
  • jti (JWT ID): Unique identifier for the JWT.

Custom Claims

You can add custom claims to include any additional information needed for your application, such as user roles, permissions, or preferences.

{
  "sub": "1234567890",
  "name": "John Doe",
  "role": "admin",
  "permissions": ["read", "write"],
  "exp": 1516242622
}

JWT Security Best Practices

  • Always Verify Signatures: Never trust a JWT without verifying its signature. Decoding is not verification.
  • Use Strong Secrets: Use cryptographically strong, random secrets for HMAC algorithms. Never use weak or predictable secrets.
  • Set Short Expiration Times: Use short-lived tokens (15 minutes to 1 hour) and implement refresh tokens for longer sessions.
  • Validate All Claims: Check expiration, issuer, audience, and other relevant claims before accepting a token.
  • Use HTTPS: Always transmit JWTs over HTTPS to prevent interception and man-in-the-middle attacks.
  • Avoid Sensitive Data: Don't store sensitive information like passwords in JWT payloads. JWTs are encoded, not encrypted.
  • Prevent Algorithm Confusion: Always specify the expected algorithm when verifying. Don't trust the 'alg' claim blindly.
  • Implement Token Revocation: For critical applications, maintain a blacklist of revoked tokens or use short expiration times.
  • Store Securely: If storing JWTs client-side, use httpOnly cookies when possible, or secure localStorage with proper security headers.
  • Monitor and Log: Log JWT verification failures and monitor for suspicious patterns or attacks.

Security Warning: JWTs are encoded (base64), not encrypted. Anyone can decode a JWT and read its contents. Only the signature prevents tampering. Never store sensitive data in JWTs that shouldn't be visible to clients.

Conclusion

JWT tokens are powerful tools for authentication and authorization in modern web applications. Understanding their structure, how to decode them, and how to verify signatures is essential for secure API development.

Remember to always verify signatures, validate claims, use short expiration times, and follow security best practices. With proper implementation, JWTs provide a scalable, stateless solution for authentication.

Ready to decode a JWT? Use our free JWT Decoder to inspect token contents, check expiration, and understand JWT structure. No signup required, completely free, and works instantly in your browser.

Decode JWT Now →

Frequently Asked Questions

What is a JWT token?

JWT (JSON Web Token) is a compact, URL-safe token format used for securely transmitting information between parties. It consists of three parts: header, payload, and signature, separated by dots.

How do I decode a JWT token?

Use our free online JWT Decoder tool. Simply paste your JWT token, and the tool will decode the header and payload, showing you the JSON data inside. You can also decode JWTs programmatically using base64 decoding.

What information is in a JWT?

A JWT contains a header (algorithm and token type), payload (claims/data), and signature (for verification). The payload typically includes user information, expiration time, and other claims.

Is decoding a JWT secure?

Decoding a JWT only reveals the header and payload, which are base64-encoded (not encrypted). Anyone can decode a JWT, but only those with the secret key can verify its signature and trust its contents.

What does JWT signature verification do?

Signature verification ensures the JWT hasn't been tampered with. It uses the secret key to verify that the header and payload match the signature. Only tokens with valid signatures should be trusted.

How do I check if a JWT is expired?

Check the 'exp' (expiration) claim in the payload. It's a Unix timestamp. If the current time is greater than the exp value, the token is expired. Our JWT Decoder automatically checks expiration.

What are JWT claims?

Claims are pieces of information in the JWT payload. Standard claims include 'iss' (issuer), 'exp' (expiration), 'sub' (subject), 'iat' (issued at), and 'aud' (audience). You can also add custom claims.

Can I decode a JWT without the secret?

Yes! Decoding only requires base64 decoding, which anyone can do. However, verifying the signature requires the secret key. Always verify signatures before trusting JWT contents.

What's the difference between JWT decode and verify?

Decoding extracts the data from a JWT (anyone can do this). Verifying checks that the signature is valid and the token hasn't been tampered with (requires the secret key).

How do I use JWTs in API authentication?

Include the JWT in the Authorization header as 'Bearer <token>'. The server decodes and verifies the token to authenticate the request. JWTs are stateless, making them ideal for APIs.

Explore these related free tools to enhance your productivity and workflow.

Related Articles