In this article
February 27, 2025
February 27, 2025

How to add custom claims to JWTs

Your auth system can issue a JWT with user details, enabling API routes to decode and use claims without extra queries.

JSON Web Tokens (JWTs) are a compact, secure way to convey user identity and authorization details.

They package user information—like IDs, roles, and permissions—into a token that’s easy to verify and use across services.

Enriching JSON Web Tokens with application logic

Imagine an e-commerce scenario where your customer signs in to make purchases.

Your auth system can issue a JWT containing essential details for your user so that your API routes can decode and use the information in the claims without making additional queries or using redundant data access patterns:

  • User ID: Identifies the customer.
  • Roles: Specifies if the user is a regular buyer or a premium member.
  • Permissions: Determines access to special discounts or admin features.
  • Additional Info: Such as membership level or last login time.

Here’s an example JWT payload for a signed-in e-commerce user:

{
  "sub": "9876543210",
  "name": "Jane Smith",
  "roles": ["buyer", "premium"],
  "permissions": {
    "discountAccess": true,
    "returnPolicyOverride": false
  },
  "iat": 1616688764,
  "exp": 1616692364,
  "iss": "ExampleMart",
  "aud": "example-customers"
}

Creating a custom JWT in Node.js

Below is a Node.js snippet using the jsonwebtoken library to generate a JWT with custom claims:

const jwt = require('jsonwebtoken');

// Define the payload with custom claims
const payload = {
  sub: '9876543210',              // Unique user ID
  name: 'Jane Smith',             // Customer name
  roles: ['buyer', 'premium'],    // Role-based access control
  permissions: {                  // Custom permissions
    discountAccess: true,
    returnPolicyOverride: false
  }
};

// Secure key stored in environment variables
const secret = process.env.JWT_SECRET;

// Token options including issuer and audience for additional security
const tokenOptions = {
  expiresIn: '1h',                // Token validity period
  issuer: 'ExampleMart',
  audience: 'example-customers'
};

// Sign the token
const token = jwt.sign(payload, secret, tokenOptions);
console.log('Generated JWT:', token);

// Verify and decode the JWT
try {
  const decoded = jwt.verify(token, secret);
  console.log('Decoded JWT payload:', decoded);
} catch (err) {
  console.error('Token verification failed:', err);
}

The resulting JWT encapsulates user identity and access details, making them easily accessible in your API routes.

Key takeaways
  • JWT structure: Consists of a header, payload, and signature.
  • Custom claims: Tailor the payload to include the data your application needs.
  • Security best practices: Set expirations, validate issuers and audiences, and avoid storing sensitive information.

This site uses cookies to improve your experience. Please accept the use of cookies on this site. You can review our cookie policy here and our privacy policy here. If you choose to refuse, functionality of this site will be limited.