Nest.js - Guards

level·2023년 8월 30일

TIL

목록 보기
89/95

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';
  }
}

0개의 댓글