Guards(가드)
Nest.js의 중요한 기능 중 하나로, 라우터 핸들러에 들어오는 요청을 검사하고, 필요한 조건이 충족되지 않는 경우 요청을 처리하지 않거나 거부하는 역할
주로 인증, 권한 부여 및 요청 유효성 검사 등을 처리하는데 사용
AuthGuard, RolesGuard, 등 빌트인 Guards: Nest.js는 일반적인 몇 가지 미리 정의된 가드를 제공
AuthGuard: 인증된 사용자만 특정 라우터에 접근할 수 있게함
RolesGuard: 사용자 역할에 따라 접근 권한을 제한
커스텀 Guards: Nest.js는 필요에 따라 직접 가드를 정의하여 사용할 수 있도록 허용
커스텀 가드는 CanActivate, CanActivateChild, CanActivateOnMethod 등의 데코레이터를 사용하여 라우터 핸들러에 적용가능
이를 통해 요청을 처리하기 전에 다양한 조건을 검사하고 필요한 동작을 수행할 수 있다
메타데이터 활용: Guards는 라우터 핸들러에 적용되기 전에 실행되며, 메타데이터를 활용하여 가드가 수행해야 할 동작을 지정
이를 통해 인증, 권한 부여, 데이터 유효성 검사 등 다양한 작업을 수행
Guard 체인: 여러 개의 가드를 하나의 라우터 핸들러에 적용
이때 각 가드는 순차적으로 실행되며, 하나의 가드가 실패하면 나머지 가드는 실행되지 않고 요청이 거부됨
요청 거부 및 리다이렉션: 가드는 true나 false를 반환하여 요청을 허용 또는 거부가능
canActivate 메서드 내에서 ExecutionContext를 통해 Response 객체에 접근하여 리다이렉션을 수행
의존성 주입: Guards도 의존성 주입(Dependency Injection)을 지원하며, 서비스나 다른 컴포넌트와의 연동을 통해 보다 유연하고 재사용 가능한 가드를 구성
전역 가드와 모듈 가드: Guards는 전역적으로 애플리케이션 레벨에서도 설정할 수 있고, 특정 모듈 내에서만 적용가능
이를 통해 보안 정책을 전역적으로 또는 모듈별로 관리
예)
RolesGuard
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.get<string[]>('roles', context.getHandler());
if (!requiredRoles) {
return true; // No roles are required, allow access
}
const request = context.switchToHttp().getRequest();
const user = request.user; // Assuming user information is stored in the request
return requiredRoles.some(role => user.roles.includes(role));
}
}
Guard 적용하기
import { Controller, Get, UseGuards } from '@nestjs/common';
import { RolesGuard } from './roles.guard';
@Controller('items')
export class ItemsController {
@Get()
@UseGuards(RolesGuard)
findAll() {
// This code will only be executed if the RolesGuard allows access based on user roles
return 'List of items';
}
}
메타데이터 설정하기
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
라우터 핸들러에 가드와 메타데이터 적용하기
import { Controller, Get, UseGuards } from '@nestjs/common';
import { RolesGuard } from './roles.guard';
import { Roles } from './roles.decorator';
@Controller('admin')
export class AdminController {
@Get()
@UseGuards(RolesGuard)
@Roles('admin') // Specify required roles as metadata
adminOnly() {
return 'Admin dashboard';
}
}