JWT Token Extraction

The @nestjs-cognito/core package provides flexible JWT token extraction capabilities, allowing you to customize how JWT tokens are retrieved from incoming requests. This is particularly useful for different authentication strategies like cookie-based authentication.

Built-in Extractors

BearerJwtExtractor (Default)

The BearerJwtExtractor extracts JWT tokens from the Authorization: Bearer <token> header. This is the most common method for JWT token authentication in REST APIs.

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

// This is the default extractor, no configuration needed
// But you can explicitly configure it:
CognitoModule.register({
  jwtExtractor: new BearerJwtExtractor(),
  // ... other configuration
})

Supported request types:

  • HTTP requests (request.headers.authorization)
  • WebSocket handshake headers (request.handshake.headers.authorization)

CookieJwtExtractor

The CookieJwtExtractor extracts JWT tokens from HTTP-only cookies. This is ideal for web applications that store JWT tokens in secure cookies for enhanced security.

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

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

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

Custom JWT Extractors

You can create custom JWT extractors by implementing the CognitoJwtExtractor interface. This allows you to extract tokens from any source you need.

Interface Definition

interface CognitoJwtExtractor {
  /**
   * Determines if the request contains authentication information.
   * @param request - The request object (HTTP, WebSocket, etc.)
   * @returns True if authentication info is present, false otherwise
   */
  hasAuthenticationInfo(request: any): boolean;

  /**
   * Extracts the JWT token from the request.
   * @param request - The request object (HTTP, WebSocket, etc.)
   * @returns The JWT token string or null if not found
   */
  getAuthorizationToken(request: any): string | null;
}

Custom Header Extractor Example

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

class CustomHeaderJwtExtractor implements CognitoJwtExtractor {
  constructor(private readonly headerName: string = 'x-auth-token') {}

  hasAuthenticationInfo(request: any): boolean {
    // Check if request has authentication information
    return Boolean(request.headers[this.headerName]);
  }

  getAuthorizationToken(request: any): string | null {
    // Extract and return the JWT token
    return request.headers[this.headerName] || null;
  }
}

// Use your custom extractor
CognitoModule.register({
  jwtExtractor: new CustomHeaderJwtExtractor('x-custom-token'),
  // ... other configuration
})

Multi-source Extractor Example

import { CognitoJwtExtractor, BearerJwtExtractor, CookieJwtExtractor } from "@nestjs-cognito/core";

class MultiSourceJwtExtractor implements CognitoJwtExtractor {
  private extractors = [
    new BearerJwtExtractor(),
    new CookieJwtExtractor('access_token'),
    new CookieJwtExtractor('jwt_token')
  ];

  hasAuthenticationInfo(request: any): boolean {
    return this.extractors.some(extractor => 
      extractor.hasAuthenticationInfo(request)
    );
  }

  getAuthorizationToken(request: any): string | null {
    for (const extractor of this.extractors) {
      if (extractor.hasAuthenticationInfo(request)) {
        return extractor.getAuthorizationToken(request);
      }
    }
    return null;
  }
}

Injection in Services

You can inject the JWT extractor in your services for manual token extraction:

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

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

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

  validateTokenPresence(request: any): boolean {
    return this.jwtExtractor.hasAuthenticationInfo(request);
  }
}

Integration with Authentication Guards

The JWT extractors work seamlessly with @nestjs-cognito/auth guards. The guards automatically use the configured extractor to retrieve tokens from requests before verification.

import { CognitoAuthenticationGuard } from '@nestjs-cognito/auth';

@Controller('protected')
@UseGuards(CognitoAuthenticationGuard)
export class ProtectedController {
  @Get()
  getProtectedData() {
    // The guard will use your configured JWT extractor
    // to retrieve and verify the token automatically
    return { message: 'This is protected data' };
  }
}

This integration ensures that your custom extraction logic is consistently applied across your entire application.