Guards
Nest.js의 Guards에 대해 정리하였습니다.
< Guards >
Guards have a single responsibility. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as authorization.
A guard is a class annotated with the @Injectable( ) decorator, which implements the CanActivate interface.
< HINT >
Guards are executed after all middleware, but before any interceptor or pipe.
< Authorization guard >
It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.
Ex : auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return validateRequest(request);
}
}
Every guard must implement a canActivate( ) function. This function should return a boolean, indicating whether the current request is allowed or not. It can return the response either synchronously or asynchronously (via a Promise or Observable). Nest uses the return value to control the next action:
- if it returns true , the request will be processed.
- if it returns false , Nest will deny the request.
< Binding guard >
Like pipes and exception filters, guards can be controller-scoped, method-scoped, or global-scoped.
Controllr-scoped
@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
Global-scoped
const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_GUARD,
useClass: RolesGuard,
},
],
})
export class AppModule {}
< Setting roles per handler >
Nest provides the ability to attach custom metadata to route handlers through either decorators created via Reflector#createDecorator static method, or the built-in @SetMetadata( ) decorator.
Ex)
import { Reflector } from '@nestjs/core';
export const Roles = Reflector.createDecorator<string[]>();
: The Roles decorator here is a function that takes a single argument of type string[].
@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
: Here we've attached the Roles decorator metadata to the create() method, indicating that only users with the admin role should be allowed to access this route.
< Example >
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get(Roles, context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return matchRoles(roles, user.roles);
}
}
Reference : https://docs.nestjs.com/guards
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com