JSPM

  • Created
  • Published
  • Downloads 10277
  • Score
    100M100P100Q141065F
  • License MIT

Cognito Provider for NestJS

Package Exports

  • @nestjs-cognito/core
  • @nestjs-cognito/core/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@nestjs-cognito/core) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

NestJS-Cognito Core

Coverage Status npm License: MIT

Overview

The core package provides essential AWS Cognito integration functionality for NestJS applications. It serves as the foundation for the @nestjs-cognito ecosystem, offering JWT verification, token extraction, and Cognito Identity Provider integration with comprehensive dependency injection support.

Features

  • JWT Verification - Cognito JWT and RSA-based token verification with JWKS caching
  • Token Extraction - Flexible token extraction from headers, cookies, or custom sources
  • AWS Integration - Native AWS Cognito Identity Provider SDK integration
  • Type Safety - Full TypeScript support with comprehensive type definitions
  • Multi-Pool Support - Handle multiple Cognito User Pools and issuers
  • Dependency Injection - First-class NestJS DI support with decorators

Installation

npm install @nestjs-cognito/core

Quick Start

Basic Configuration

import { Module } from '@nestjs/common';
import { CognitoModule } from '@nestjs-cognito/core';

@Module({
  imports: [
    CognitoModule.register({
      jwtVerifier: {
        userPoolId: 'us-east-1_xxxxx',
        clientId: 'your-client-id',
        tokenUse: 'access', // 'access' | 'id' | null
      },
    }),
  ],
})
export class AppModule {}

Async Configuration

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CognitoModule } from '@nestjs-cognito/core';

@Module({
  imports: [
    CognitoModule.registerAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => ({
        jwtVerifier: {
          userPoolId: config.get('COGNITO_USER_POOL_ID'),
          clientId: config.get('COGNITO_CLIENT_ID'),
          tokenUse: 'access',
        },
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Core Components

JWT Verification

The package provides two JWT verification strategies. Both perform comprehensive token validation including expiration, audience, issuer, and token use verification.

Cognito JWT Verifier

Verifies tokens issued by AWS Cognito User Pools using aws-jwt-verify:

import {
  CognitoJwtVerifier,
  InjectCognitoJwtVerifier
} from '@nestjs-cognito/core';

export class AuthService {
  constructor(
    @InjectCognitoJwtVerifier()
    private readonly jwtVerifier: CognitoJwtVerifier,
  ) {}

  async validateToken(token: string) {
    try {
      const payload = await this.jwtVerifier.verify(token);
      return { valid: true, payload };
    } catch (error) {
      return { valid: false, error: error.message };
    }
  }
}

Configuration:

// Single User Pool
CognitoModule.register({
  jwtVerifier: {
    userPoolId: 'us-east-1_xxxxx',
    clientId: 'your-client-id',
    tokenUse: 'access', // 'access', 'id', or null for both
  },
})

// Multiple User Pools
CognitoModule.register({
  jwtVerifier: [
    {
      userPoolId: 'us-east-1_pool1',
      clientId: 'client1',
      tokenUse: 'access',
    },
    {
      userPoolId: 'us-east-1_pool2',
      clientId: 'client2',
      tokenUse: 'id',
    },
  ],
})

RSA JWT Verifier

Verifies JWTs using RSA public keys from any JWKS endpoint:

import {
  JwtRsaVerifier,
  InjectCognitoJwtVerifier
} from '@nestjs-cognito/core';

export class AuthService {
  constructor(
    @InjectCognitoJwtVerifier()
    private readonly jwtVerifier: JwtRsaVerifier,
  ) {}

  async validateToken(token: string) {
    const payload = await this.jwtVerifier.verify(token);
    return payload;
  }
}

Configuration:

// Single Issuer
CognitoModule.register({
  jwtRsaVerifier: {
    issuer: 'https://your-issuer.com',
    jwksUri: 'https://your-issuer.com/.well-known/jwks.json',
  },
})

// Multiple Issuers
CognitoModule.register({
  jwtRsaVerifier: [
    {
      issuer: 'https://issuer1.com',
      jwksUri: 'https://issuer1.com/.well-known/jwks.json',
    },
    {
      issuer: 'https://issuer2.com',
      jwksUri: 'https://issuer2.com/.well-known/jwks.json',
    },
  ],
})

Note: InjectCognitoJwtVerifier() works with both verifier types, but you must configure only one type (jwtVerifier or jwtRsaVerifier) in your module.

JWT Claims Verification

Both verifiers perform the following validations:

  • Expiration (exp) - Ensures the token hasn't expired
  • Audience (aud/client_id) - Validates the token's intended recipient
  • Issuer (iss) - Verifies the token was issued by the expected authority
  • Token Use (token_use) - Confirms the token type (access/id)

Token Extraction

Flexible JWT token extraction from various sources.

Built-in Extractors

Bearer Token (Default):

import { BearerJwtExtractor } from '@nestjs-cognito/core';

CognitoModule.register({
  jwtExtractor: new BearerJwtExtractor(), // Optional, this is the default
  // ... other config
})

Extracts tokens from: Authorization: Bearer <token>

Cookie-Based:

import { CookieJwtExtractor } from '@nestjs-cognito/core';

CognitoModule.register({
  jwtExtractor: new CookieJwtExtractor('access_token'), // cookie name
  // ... other config
})

Using in Services:

import {
  CognitoJwtExtractor,
  InjectCognitoJwtExtractor,
} from '@nestjs-cognito/core';

export class AuthService {
  constructor(
    @InjectCognitoJwtExtractor()
    private readonly jwtExtractor: CognitoJwtExtractor,
  ) {}

  extractToken(request: any): string | null {
    if (this.jwtExtractor.hasAuthenticationInfo(request)) {
      return this.jwtExtractor.getAuthorizationToken(request);
    }
    return null;
  }
}

Custom Extractors

Create custom token extractors by implementing the CognitoJwtExtractor interface:

import { CognitoJwtExtractor } from '@nestjs-cognito/core';

export class CustomHeaderExtractor implements CognitoJwtExtractor {
  hasAuthenticationInfo(request: any): boolean {
    return Boolean(request.headers['x-custom-auth']);
  }

  getAuthorizationToken(request: any): string | null {
    const header = request.headers['x-custom-auth'];
    if (!header) return null;

    // Extract token from custom format
    const match = header.match(/^Token (.+)$/);
    return match ? match[1] : null;
  }
}

// Register in module
CognitoModule.register({
  jwtExtractor: new CustomHeaderExtractor(),
  // ... other config
})

AWS Cognito Identity Provider

Direct access to AWS Cognito Identity Provider for user management operations:

import { CognitoIdentityProvider } from '@aws-sdk/client-cognito-identity-provider';
import { InjectCognitoIdentityProvider } from '@nestjs-cognito/core';

export class UserService {
  constructor(
    @InjectCognitoIdentityProvider()
    private readonly cognito: CognitoIdentityProvider,
  ) {}

  async getUserInfo(username: string) {
    const response = await this.cognito.adminGetUser({
      UserPoolId: 'us-east-1_xxxxx',
      Username: username,
    });
    return response;
  }

  async listUsers(limit = 10) {
    const response = await this.cognito.listUsers({
      UserPoolId: 'us-east-1_xxxxx',
      Limit: limit,
    });
    return response.Users;
  }
}

Configuration with Identity Provider:

CognitoModule.register({
  identityProvider: {
    region: 'us-east-1',
    credentials: {
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    },
  },
  jwtVerifier: {
    userPoolId: 'us-east-1_xxxxx',
    clientId: 'your-client-id',
    tokenUse: 'access',
  },
})

Advanced Configuration

JWK Cache Configuration

Configure JWKS key caching for improved performance:

CognitoModule.register({
  jwtVerifier: {
    userPoolId: 'us-east-1_xxxxx',
    clientId: 'your-client-id',
    tokenUse: 'access',
    additionalProperties: {
      jwksCache: {
        expiryTimeInHours: 24, // Cache duration
      },
    },
  },
})

Multi-Pool Configuration with Individual Settings

CognitoModule.register({
  jwtVerifier: [
    {
      userPoolId: 'us-east-1_pool1',
      clientId: 'client1',
      tokenUse: 'access',
      additionalProperties: {
        jwksCache: {
          expiryTimeInHours: 24,
        },
      },
    },
    {
      userPoolId: 'eu-west-1_pool2',
      clientId: 'client2',
      tokenUse: 'id',
      additionalProperties: {
        jwksCache: {
          expiryTimeInHours: 12,
        },
      },
    },
  ],
})
CognitoModule.register({
  jwtExtractor: new CookieJwtExtractor('jwt_token'),
  jwtVerifier: {
    userPoolId: 'us-east-1_xxxxx',
    clientId: 'your-client-id',
    tokenUse: 'id',
  },
})

Complete Configuration Example

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CognitoModule, CookieJwtExtractor } from '@nestjs-cognito/core';

@Module({
  imports: [
    CognitoModule.registerAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => ({
        // AWS Cognito Identity Provider configuration
        identityProvider: {
          region: config.get('AWS_REGION'),
          credentials: {
            accessKeyId: config.get('AWS_ACCESS_KEY_ID'),
            secretAccessKey: config.get('AWS_SECRET_ACCESS_KEY'),
          },
        },

        // JWT token extraction strategy
        jwtExtractor: new CookieJwtExtractor('access_token'),

        // JWT verification configuration
        jwtVerifier: {
          userPoolId: config.get('COGNITO_USER_POOL_ID'),
          clientId: config.get('COGNITO_CLIENT_ID'),
          tokenUse: 'access',
          additionalProperties: {
            jwksCache: {
              expiryTimeInHours: 24,
            },
          },
        },
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Integration with Other Packages

The Core package provides the foundational components used by:

For full authentication features (guards, decorators, authorization), use the @nestjs-cognito/auth package.

Documentation

For comprehensive guides, examples, and API reference visit the official documentation.

License

@nestjs-cognito/core is MIT licensed.