Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@nestjs-cognito/core

Lokicoule49.6kMIT2.4.1TypeScript support: included

Cognito Provider for NestJS

nestjs, nestjs-cognito, nest, aws, aws-cognito, cognito, cognito-provider, aws-sdk, client-cognito-identity-provider, identity-provider, user-pool, authentication, jwt-verify, typescript, module, provider

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.

changelog

Changelog:

Latest Updates

Added support for HTTP-only cookies with graphql-ws subscriptions. Previously, when using graphql-ws and subscriptions, HTTP-only cookies were missing at the point of authentication and would fail.

Issue: The AuthenticationGuard in the GraphQL package builds a GQL context and returns a request, but downstream authentication expects a cookies property to be present, which works for HTTP requests ✅ but not for WebSockets 🤔.

Solution: Enhanced cookie extraction to support the graphql-ws context structure where cookies are passed in ctx.request?.extra?.request?.headers?.cookie.

Technical Details:

  • The CookieJwtExtractor now properly handles WebSocket contexts
  • Cookies are extracted from the nested structure: ctx.request?.extra?.request?.headers?.cookie
  • This enables seamless authentication for GraphQL subscriptions using HTTP-only cookies
  • Maintains backward compatibility with existing HTTP cookie authentication

Usage: No changes required for existing implementations. The enhanced cookie extraction works automatically with graphql-ws subscriptions.

@nestjs-cognito/core:

  • The code for importing and registering the CognitoAuthModule has changed.
  • The old code:
import { CognitoAuthModule } from "@nestjs-cognito/auth";
import { Module } from "@nestjs/common";

@Module({
  imports: [
    CognitoAuthModule.register({
      region: region,
    }),
  ],
})
export class AppModule {}
  • The new code:
import { CognitoAuthModule } from "@nestjs-cognito/auth";
import { Module } from "@nestjs/common";

@Module({
  imports: [
    CognitoAuthModule.register({
      jwtVerifier: {
        userPoolId: "user_pool_id",
        clientId: "client_id",
        tokenUse: "id",
      },
    }),
  ],
})
export class AppModule {}

@nestjs-cognito/auth:

  • Replaced "CurrentUser" with "CognitoUser".
  • "CurrentUser" is now deprecated.

@nestjs-cognito/graphql:

  • Added the "Gql" prefix before all decorators.
  • "Authentication" and "Authorization" decorators are now deprecated for the graphql module and have been replaced by "GqlAuthentication" and "GqlAuthorization".
  • Replaced "CurrentUser" with "GqlCognitoUser".
  • "CurrentUser" is now deprecated.