or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-jsonwebtoken

JSON Web Token implementation for Node.js supporting both symmetric and asymmetric cryptographic algorithms

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/jsonwebtoken@9.0.x

To install, run

npx @tessl/cli install tessl/npm-jsonwebtoken@9.0.0

index.mddocs/

jsonwebtoken

A comprehensive JSON Web Token (JWT) implementation for Node.js providing secure token creation, verification, and decoding with support for both symmetric (HMAC) and asymmetric (RSA, ECDSA) cryptographic algorithms.

Package Information

  • Package Name: jsonwebtoken
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install jsonwebtoken

Core Imports

const jwt = require('jsonwebtoken');
const { sign, verify, decode, JsonWebTokenError, TokenExpiredError, NotBeforeError } = require('jsonwebtoken');

For ES modules:

import jwt from 'jsonwebtoken';
import { sign, verify, decode, JsonWebTokenError, TokenExpiredError, NotBeforeError } from 'jsonwebtoken';

Basic Usage

const jwt = require('jsonwebtoken');

// Sign a token with HMAC
const token = jwt.sign({ userId: 123, username: 'alice' }, 'your-secret-key', {
  expiresIn: '1h'
});

// Verify a token
try {
  const decoded = jwt.verify(token, 'your-secret-key');
  console.log(decoded); // { userId: 123, username: 'alice', iat: ..., exp: ... }
} catch (err) {
  if (err instanceof jwt.TokenExpiredError) {
    console.log('Token expired');
  } else {
    console.log('Invalid token');
  }
}

// Decode without verification (unsafe for untrusted tokens)
const payload = jwt.decode(token);

Architecture

The jsonwebtoken library is built around three core operations:

  • Token Signing: Creates JWT tokens with configurable claims and cryptographic algorithms
  • Token Verification: Validates JWT tokens with security checks for timing, audience, issuer, and signature
  • Token Decoding: Extracts payload data without cryptographic verification (for trusted contexts only)
  • Error Handling: Specialized error classes for different failure modes (expiration, malformation, invalid signature)

The library supports all standard JWT algorithms including HMAC (HS256/384/512), RSA (RS256/384/512, PS256/384/512), and ECDSA (ES256/384/512).

Capabilities

Token Signing

Creates and signs JWT tokens with configurable options and claims.

/**
 * Signs a JWT token with the provided payload and secret/key
 * @param payload - Object literal, buffer, or string representing valid JSON
 * @param secretOrPrivateKey - Secret string, buffer, object, or KeyObject for signing
 * @param options - Optional signing configuration
 * @param callback - Optional callback for asynchronous operation
 * @returns JWT string (sync) or calls callback with JWT (async)
 */
function sign(payload: any, secretOrPrivateKey: string | Buffer | object | KeyObject, options?: SignOptions, callback?: SignCallback): string;

interface SignOptions {
  algorithm?: Algorithm;
  expiresIn?: string | number;
  notBefore?: string | number;
  audience?: string | string[];
  issuer?: string;
  jwtid?: string;
  subject?: string;
  noTimestamp?: boolean;
  header?: object;
  keyid?: string;
  mutatePayload?: boolean;
  allowInsecureKeySizes?: boolean;
  allowInvalidAsymmetricKeyTypes?: boolean;
  encoding?: string;
}

type Algorithm = 
  | 'HS256' | 'HS384' | 'HS512'
  | 'RS256' | 'RS384' | 'RS512'
  | 'PS256' | 'PS384' | 'PS512'
  | 'ES256' | 'ES384' | 'ES512'
  | 'none';

type SignCallback = (err: Error | null, token?: string) => void;

Usage Examples:

// Synchronous signing with HMAC
const token = jwt.sign({ foo: 'bar' }, 'secret', { expiresIn: '1h' });

// Asynchronous signing
jwt.sign({ foo: 'bar' }, 'secret', { expiresIn: '1h' }, (err, token) => {
  if (err) throw err;
  console.log(token);
});

// RSA signing
const fs = require('fs');
const privateKey = fs.readFileSync('private.key');
const token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });

// Custom claims
const token = jwt.sign(
  { userId: 123 },
  'secret',
  {
    expiresIn: '24h',
    audience: 'my-app',
    issuer: 'my-service',
    subject: 'user-auth'
  }
);

Token Verification

Verifies JWT tokens with comprehensive security validation.

/**
 * Verifies a JWT token and returns the decoded payload
 * @param token - JWT string to verify
 * @param secretOrPublicKey - Secret/key for verification or callback function
 * @param options - Optional verification configuration
 * @param callback - Optional callback for asynchronous operation
 * @returns Decoded payload (sync) or calls callback with payload (async)
 */
function verify(token: string, secretOrPublicKey: string | Buffer | KeyObject | GetPublicKeyCallback, options?: VerifyOptions, callback?: VerifyCallback): any;

interface VerifyOptions {
  algorithms?: Algorithm[];
  audience?: string | RegExp | (string | RegExp)[];
  complete?: boolean;
  issuer?: string | string[];
  jwtid?: string;
  ignoreExpiration?: boolean;
  ignoreNotBefore?: boolean;
  subject?: string;
  clockTolerance?: number;
  maxAge?: string | number;
  clockTimestamp?: number;
  nonce?: string;
  allowInvalidAsymmetricKeyTypes?: boolean;
}

type GetPublicKeyCallback = (header: JwtHeader, callback: (err: any, key?: string | Buffer | KeyObject) => void) => void;
type VerifyCallback = (err: Error | null, payload?: any) => void;

interface JwtHeader {
  alg: Algorithm;
  typ?: string;
  kid?: string;
}

Usage Examples:

// Basic verification
const decoded = jwt.verify(token, 'secret');

// Async verification with error handling
jwt.verify(token, 'secret', (err, decoded) => {
  if (err) {
    if (err instanceof jwt.TokenExpiredError) {
      console.log('Token expired at:', err.expiredAt);
    } else if (err instanceof jwt.NotBeforeError) {
      console.log('Token not active until:', err.date);
    } else {
      console.log('Token invalid:', err.message);
    }
  } else {
    console.log('Valid token:', decoded);
  }
});

// Verification with audience check
const decoded = jwt.verify(token, 'secret', {
  audience: 'my-app',
  issuer: 'my-service'
});

// Dynamic key resolution
function getKey(header, callback) {
  // Fetch key based on header.kid
  const key = getPublicKeyFromSomewhere(header.kid);
  callback(null, key);
}

jwt.verify(token, getKey, (err, decoded) => {
  console.log(decoded);
});

// Complete token information
const result = jwt.verify(token, 'secret', { complete: true });
// result = { header: {...}, payload: {...}, signature: "..." }

Token Decoding

Decodes JWT tokens without cryptographic verification.

/**
 * Decodes a JWT token without verifying the signature (unsafe for untrusted tokens)
 * @param token - JWT string to decode
 * @param options - Optional decoding configuration
 * @returns Decoded payload object or null if invalid
 */
function decode(token: string, options?: DecodeOptions): any | null;

interface DecodeOptions {
  complete?: boolean;
  json?: boolean;
}

Usage Examples:

// Basic decoding
const payload = jwt.decode(token);

// Complete token structure
const decoded = jwt.decode(token, { complete: true });
// decoded = { header: {...}, payload: {...}, signature: "..." }

// Force JSON parsing
const payload = jwt.decode(token, { json: true });

Error Handling

Specialized error classes for different JWT validation failures.

/**
 * Base error class for JWT-related errors
 */
class JsonWebTokenError extends Error {
  name: 'JsonWebTokenError';
  message: string;
  inner?: Error;
}

/**
 * Error thrown when a token has expired
 */
class TokenExpiredError extends JsonWebTokenError {
  name: 'TokenExpiredError';
  message: 'jwt expired';
  expiredAt: Date;
}

/**
 * Error thrown when a token is not yet active (nbf claim)
 */
class NotBeforeError extends JsonWebTokenError {
  name: 'NotBeforeError';
  message: 'jwt not active';
  date: Date;
}

Common Error Messages:

  • JsonWebTokenError: 'invalid token', 'jwt malformed', 'jwt signature is required', 'invalid signature'
  • JsonWebTokenError: 'jwt audience invalid', 'jwt issuer invalid', 'jwt id invalid', 'jwt subject invalid'
  • TokenExpiredError: 'jwt expired'
  • NotBeforeError: 'jwt not active'

Types

// Supported cryptographic algorithms
type Algorithm = 
  | 'HS256' | 'HS384' | 'HS512'  // HMAC with SHA
  | 'RS256' | 'RS384' | 'RS512'  // RSASSA-PKCS1-v1_5 with SHA
  | 'PS256' | 'PS384' | 'PS512'  // RSASSA-PSS with SHA (Node.js 6.12+ or 8+)
  | 'ES256' | 'ES384' | 'ES512'  // ECDSA with SHA
  | 'none';                      // No signature

// Standard JWT header structure
interface JwtHeader {
  alg: Algorithm;
  typ?: 'JWT';
  kid?: string; // Key ID
}

// Complete JWT structure when using decode({ complete: true })
interface CompleteJwt {
  header: JwtHeader;
  payload: any;
  signature: string;
}

// Validation result when using verify({ complete: true })
interface CompleteVerifyResult {
  header: JwtHeader;
  payload: any;
  signature: string;
}

Security Considerations

Key Requirements

  • HMAC (HS256/384/512): Requires symmetric secret key (string, Buffer, or KeyObject)
  • RSA (RS/PS algorithms): Requires minimum 2048-bit modulus (configurable with allowInsecureKeySizes)
  • ECDSA (ES algorithms): Requires appropriate elliptic curve (P-256, P-384, P-521)

Algorithm Security

  • Default algorithm selection based on key type prevents algorithm confusion attacks
  • Explicit algorithm specification recommended for production use
  • none algorithm requires explicit inclusion in algorithms array for verification

Time-based Validation

  • Automatic validation of exp (expiration), nbf (not before), and iat (issued at) claims
  • Configurable clock tolerance for distributed systems
  • maxAge option for additional age-based validation

Best Practices

// Specify allowed algorithms explicitly
const decoded = jwt.verify(token, publicKey, {
  algorithms: ['RS256'],
  audience: 'my-app',
  issuer: 'trusted-issuer'
});

// Use asymmetric algorithms for distributed systems
const token = jwt.sign(payload, privateKey, {
  algorithm: 'RS256',
  expiresIn: '15m',
  audience: 'api-client',
  issuer: 'auth-service'
});

// Handle errors appropriately
try {
  const decoded = jwt.verify(token, secret);
  // Process valid token
} catch (err) {
  if (err instanceof jwt.TokenExpiredError) {
    // Handle expired token (maybe refresh)
  } else if (err instanceof jwt.JsonWebTokenError) {
    // Handle invalid token
  }
}