@nestjs-cognito/auth
v1.1.7
Published
Auth Module for NestJS and Cognito
Downloads
18,173
Readme
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 theAuthenticationGuard
to a controller and ensure that the user is authenticated. - Use the
@Authorization
decorator or the@UseGuards(AuthorizationGuard)
syntax to apply theAuthorizationGuard
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
}
AuthenticationGuard
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 { AuthenticationGuard } from "@nestjs-cognito/auth";
import { UseGuards } from "@nestjs/common";
@Controller("dogs")
@UseGuards(AuthenticationGuard)
export class DogsController {
// Your routes here
}
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";
}
}
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.