@nestjs-cognito/auth
TypeScript icon, indicating that this package has built-in type declarations

1.1.3 • Public • Published

@nestjs-cognito/auth

Node.js CI Coverage Status npm

Description

@nestjs-cognito/auth is a library for NestJS that provides authentication and authorization decorators and guards for applications using AWS Cognito. This library is built on top of @nestjs-cognito/core and aws-jwt-verify.

Installation

To install the library, use npm:

npm install @nestjs-cognito/auth

Configuration

The @nestjs-cognito/auth library offers both synchronous and asynchronous configuration options. To use the library, a few configuration parameters are required, including the AWS Cognito user pool ID and client ID. Detailed information about the available options can be found in the @nestjs-cognito/core documentation.

Synchronous Configuration

The @nestjs-cognito/auth library can be easily integrated into your NestJS application by importing the CognitoAuthModule from the @nestjs-cognito/auth package.

Use the CognitoAuthModule.register method with options from the CognitoModuleOptions interface

Here's an example of how you can import the CognitoAuthModule into your NestJS application:

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 {}

In this example, the CognitoAuthModule is imported and registered with the following configuration options:

  • jwtVerifier:
    • userPoolId: The ID of your AWS Cognito user pool.
    • clientId: The client ID of your AWS Cognito user pool.
    • tokenUse: The type of token to be used. It is recommended to use "id" instead of "access" token.

Note: You can also define an identity provider without importing the CognitoModule module by using the CognitoAuthModule.

Asynchronous Configuration

With CognitoModule.registerAsync you can import a ConfigModule and inject ConfigService to use it in useFactory method. Alternatively, you can use useExisting or useClass. You can find more information about asynchronous configuration in the NestJS documentation.

import { CognitoAuthModule } from "@nestjs-cognito/auth";
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";

@Module({
  imports: [
    CognitoAuthModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        jwtVerifier: {
          userPoolId: configService.get("COGNITO_USER_POOL_ID") as string,
          clientId: configService.get("COGNITO_CLIENT_ID"),
          tokenUse: "id",
        },
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Usage

Once the @nestjs-cognito/auth module is installed and configured, you can use the following decorators and guards to protect your controllers and routes.

Built-in Decorators and Guards

  • Use the @Authentication decorator or the @UseGuards(AuthenticationGuard) syntax to apply the AuthenticationGuard to a controller and ensure that the user is authenticated.
  • Use the @Authorization decorator or the @UseGuards(AuthorizationGuard) syntax to apply the AuthorizationGuard to a controller and ensure that the user is authorized.
  • Decorate method arguments with the @CognitoUser decorator to retrieve the payload information extracted from the JWT.

Note: During the authorization process, the authentication of the user is already checked, so there's no need to use the authentication guard or decorator.

In addition, you can find more details about @UseGuards decorator from the official NestJS documentation.

Authentication

@Authentication Decorator

To configure the authentication, you'll need to use the @Authentication decorator. You can add the @Authentication decorator to controllers or routes:

import { Authentication } from "@nestjs-cognito/auth";
import { Controller } from "@nestjs/common";

@Controller("dogs")
@Authentication()
export class DogsController {
  // Your routes here
}

AuthenticationGard

You can also use the AuthenticationGuard to secure individual routes or endpoint.

To use the AuthenticationGuard, you'll need to use the @UseGuards decorator:

import { Authentication } from "@nestjs-cognito/auth";
import { UseGuards } from "@nestjs/common";

@Controller("dogs")
@UseGuards(AuthenticationGuard)
export class DogsController {
  // Your routes here
}
Examples of using authentication:
import {
  Authentication,
  AuthenticationGuard,
  CognitoUser,
} from "@nestjs-cognito/auth";
import { Controller, Get, UseGuards } from "@nestjs/common";
import { CognitoJwtPayload } from "aws-jwt-verify/jwt-model";

@Controller("dogs")
@Authentication()
export class DogsController {
  @Get()
  findAll(@CognitoUser("email") email: string): string {
    return "This action returns all my dogs";
  }
}

@Controller("cats")
@UseGuards(AuthenticationGuard)
export class CatsController {
  @Get()
  findAll(@CognitoUser(["groups", "email", "username"]) me): string {
    return "This action returns all my cats";
  }
}

@Controller("dogs")
export class DogsController {
  @Get()
  @Authentication()
  findAll(@CognitoUser() CognitoJwtPayload): string {
    return "This action returns all my dogs";
  }
}

@Controller("cats")
export class CatsController {
  @Get()
  @UseGuards(AuthenticationGuard)
  findAll(@CognitoUser(["groups", "email", "username"]) me): string {
    return "This action returns all my cats";
  }
}

Authorization

@Authorization Decorator

The @Authorization decorator can be used to secure an entire controller. You can specify the allowedGroups, requiredGroups, and/or prohibitedGroups for a given controller.

For example:

@Controller("dogs")
@Authorization({
  allowedGroups: ["user", "admin"],
  requiredGroups: ["moderator"],
  prohibitedGroups: ["visitor"],
})
export class DogsController {
  @Get()
  findAll(@CognitoUser() CognitoJwtPayload): string {
    return "This action returns all my dogs";
  }
}

You can also specify the allowedGroups as an array of strings:

@Controller("cats")
@Authorization(["user"]) // allowedGroups by default
export class CatsController {
  @Get()
  findAll(@CognitoUser("username") username: string): string {
    return "This action returns all my cats";
  }
}

AuthorizationGuard

The AuthorizationGuard can be used to secure a single route, allowing you to specify the allowedGroups, requiredGroups, and/or prohibitedGroups for a given endpoint.

For example:

@Controller("cats")
@UseGuards(
  AuthorizationGuard({
    allowedGroups: ["user", "admin"],
    requiredGroups: ["moderator"],
    prohibitedGroups: ["visitor"],
  })
)
export class CatsController {
  @Get()
  findAll(@CognitoUser("email") email: string): string {
    return "This action returns all my cats";
  }
}

You can also use the AuthorizationGuard directly on a route:

@Controller("cats")
export class CatsController {
  @Get()
  @UseGuards(AuthorizationGuard(["user", "admin"]))
  findAll(@CognitoUser() me: CognitoJwtPayload): string {
    return "This action returns all my cats";
  }
}
Examples of using authorization:
import {
  Authorization,
  AuthorizationGuard,
  CognitoUser,
} from "@nestjs-cognito/auth";
import { Controller, Get, UseGuards } from "@nestjs/common";
import { CognitoJwtPayload } from "aws-jwt-verify/jwt-model";

@Controller("dogs")
@Authorization({
  allowedGroups: ["user", "admin"],
  requiredGroups: ["moderator"],
  prohibitedGroups: ["visitor"],
})
export class DogsController {
  @Get()
  findAll(@CognitoUser() CognitoJwtPayload): string {
    return "This action returns all my dogs";
  }
}

@Controller("cats")
@Authorization(["user"]) // allowedGroups by default
export class CatsController {
  @Get()
  findAll(@CognitoUser("username") username: string): string {
    return "This action returns all my cats";
  }
}

@Controller("cats")
@UseGuards(
  AuthorizationGuard({
    allowedGroups: ["user", "admin"],
    requiredGroups: ["moderator"],
    prohibitedGroups: ["visitor"],
  })
)
export class CatsController {
  @Get()
  findAll(@CognitoUser("email") email: string): string {
    return "This action returns all my cats";
  }
}

@Controller("cats")
export class CatsController {
  @Get()
  @UseGuards(AuthorizationGuard(["user", "admin"]))
  findAll(@CognitoUser() me: CognitoJwtPayload): string {
    return "This action returns all my cats";
  }
}

@CognitoUser

To retrieve the cognito user from an incoming request, you'll need to use the @CognitoUser decorator. You can use the decorator to inject the entire CognitoJwtPayload object or specific properties from the payload, such as the username or email. Note that the cognito: namespace is automatically managed, so you don't need to include it when accessing properties such as cognito:username or cognito:groups.

It's important to note that this decorator must be used in conjunction with an authentication guard, such as Authentication or Authorization.

For example:

@Controller()
@Authentication()
export class YourController {
  @Get()
  findAll(@CognitoUser() cognitoJwtPayload: CognitoJwtPayload): string {
    return "This action returns all the data";
  }
}

Optional property name

You can specify the name of the property to inject the user into by passing a string as an argument.

import { Authentication, CognitoUser } from "@nestjs-cognito/auth";

@Controller()
@Authentication()
export class YourController {
  @Get()
  getData(@CognitoUser("email") email: string): any {
    // Use the `email` string
  }
}

Multiple properties

You can extract multiple properties from the cognito user by passing an array of strings.

import { Authentication, CognitoUser } from "@nestjs-cognito/auth";

@Controller()
@Authentication()
export class YourController {
  @Get()
  getData(
    @CognitoUser(["groups", "email", "username"])
    {
      groups,
      email,
      username,
    }: {
      groups: string[];
      email: string;
      username: string;
    }
  ): any {
    // Use the `groups` and/or `username` and `email` strings
  }
}

@PublicRoute

This decorator is used to allow route to bypass auth validation process. In the following example, because we use class decorator @Authentication we can't access to endpoint iampublic without using the @PublicRoute decorator.

@Controller("auth")
@Authentication()
export class AuthController {
  @Get("iampublic")
  @PublicRoute()
  getPublic() {
    return "public";
  }

  @Get("me-from-payload")
  getMeFromPayload(
    @CognitoUser(["username", "email", "groups"])
    {
      username,
      email,
      groups,
    }: {
      username: string;
      email: string;
      groups: string[];
    }
  ) {
    return {
      username,
      email,
      groups,
    };
  }
}

License

@nestjs-cognito/auth is MIT licensed.

Readme

Keywords

Package Sidebar

Install

npm i @nestjs-cognito/auth

Weekly Downloads

3,331

Version

1.1.3

License

MIT

Unpacked Size

79.8 kB

Total Files

124

Last publish

Collaborators

  • lokicoule