Try it yourself with our free Jwt Decoder tool — runs entirely in your browser, no signup needed.

How to Verify JWT token signatures for API Responses

How to Verify JWT Token Signatures for API Responses

Verifying JWT token signatures is a crucial step in ensuring the authenticity and integrity of API responses. When a client receives a response from an API, it's essential to verify that the response has not been tampered with or altered during transmission. In this article, we'll explore how to verify JWT token signatures for API responses, providing a quick example, real-world scenarios, best practices, common mistakes, and frequently asked questions.

Quick Example

Here's a minimal example in JavaScript/TypeScript that verifies a JWT token signature using the jsonwebtoken library:

import jwt from 'jsonwebtoken';

const secretKey = 'your-secret-key';
const token = 'your-jwt-token';

try {
  const decoded = jwt.verify(token, secretKey);
  console.log(decoded);
} catch (error) {
  console.error(error);
}

To use this example, install the jsonwebtoken library by running npm install jsonwebtoken or yarn add jsonwebtoken.

Real-World Scenarios

Scenario 1: Verifying API Response Headers

In this scenario, the API response includes a JWT token in the Authorization header. We need to verify the token signature before processing the response.

import axios from 'axios';
import jwt from 'jsonwebtoken';

const secretKey = 'your-secret-key';
const url = 'https://api.example.com/data';

axios.get(url)
  .then(response => {
    const token = response.headers.authorization;
    try {
      const decoded = jwt.verify(token, secretKey);
      console.log(decoded);
      // Process the response data
    } catch (error) {
      console.error(error);
    }
  })
  .catch(error => {
    console.error(error);
  });

Scenario 2: Verifying JWT Tokens in API Response Bodies

In this scenario, the API response includes a JWT token in the response body. We need to verify the token signature before processing the response data.

import axios from 'axios';
import jwt from 'jsonwebtoken';

const secretKey = 'your-secret-key';
const url = 'https://api.example.com/data';

axios.post(url, {
  // Request data
})
  .then(response => {
    const token = response.data.token;
    try {
      const decoded = jwt.verify(token, secretKey);
      console.log(decoded);
      // Process the response data
    } catch (error) {
      console.error(error);
    }
  })
  .catch(error => {
    console.error(error);
  });

Scenario 3: Verifying JWT Tokens with Custom Claims

In this scenario, the API response includes a JWT token with custom claims. We need to verify the token signature and extract the custom claims.

import axios from 'axios';
import jwt from 'jsonwebtoken';

const secretKey = 'your-secret-key';
const url = 'https://api.example.com/data';

axios.get(url)
  .then(response => {
    const token = response.headers.authorization;
    try {
      const decoded = jwt.verify(token, secretKey);
      const customClaims = decoded.customClaims;
      console.log(customClaims);
      // Process the custom claims
    } catch (error) {
      console.error(error);
    }
  })
  .catch(error => {
    console.error(error);
  });

Best Practices

  1. Use a secure secret key: Use a randomly generated secret key to sign and verify JWT tokens.
  2. Use a secure algorithm: Use a secure algorithm like HS256 or RS256 to sign and verify JWT tokens.
  3. Verify token signatures on every request: Verify token signatures on every request to ensure the authenticity and integrity of API responses.
  4. Use a token blacklist: Use a token blacklist to store revoked or expired tokens and reject them during verification.
  5. Implement token expiration: Implement token expiration to limit the lifetime of JWT tokens and reduce the risk of token tampering.

Common Mistakes

Mistake 1: Not Verifying Token Signatures

// Wrong code
const token = response.headers.authorization;
const decoded = jwt.decode(token);
console.log(decoded);

Corrected code:

const token = response.headers.authorization;
try {
  const decoded = jwt.verify(token, secretKey);
  console.log(decoded);
} catch (error) {
  console.error(error);
}

Mistake 2: Using Insecure Algorithms

// Wrong code
const token = jwt.sign(payload, secretKey, { algorithm: 'none' });

Corrected code:

const token = jwt.sign(payload, secretKey, { algorithm: 'HS256' });

Mistake 3: Not Handling Errors

// Wrong code
try {
  const decoded = jwt.verify(token, secretKey);
  console.log(decoded);
} catch (error) {
  // Ignore error
}

Corrected code:

try {
  const decoded = jwt.verify(token, secretKey);
  console.log(decoded);
} catch (error) {
  console.error(error);
  // Handle error
}

FAQ

Q: What is the difference between jwt.verify() and jwt.decode()?

A: jwt.verify() verifies the token signature and returns the decoded payload, while jwt.decode() only returns the decoded payload without verifying the token signature.

Q: Can I use a different secret key for each API endpoint?

A: No, it's recommended to use a single secret key for all API endpoints to simplify token verification and management.

Q: How do I handle token expiration?

A: Implement token expiration by setting a reasonable token lifetime and verifying the token's expiration date during verification.

Q: Can I use JWT tokens with custom claims?

A: Yes, you can use JWT tokens with custom claims by adding custom data to the payload before signing the token.

Q: How do I handle token revocation?

A: Implement token revocation by storing revoked tokens in a token blacklist and rejecting them during verification.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp