TypeORM과 Guard를 활용한 인증 처리 이해하기

yujin·2024년 1월 2일
0

TIL

목록 보기
25/48
post-thumbnail

TypeORM과 Guard를 활용한 인증 처리 이해하기


1. Guard란?

Guard는 Nest.js의 요청 처리 파이프라인 중 하나로, 특정 라우트 핸들러가 실행되기 전에 요청을 검사하고, 필요에 따라 요청을 거부하는 역할을 한다.

2. TypeORM과 Guard의 결합

TypeORM과 Guard를 결합하면, 데이터베이스 엔티티에 대한 접근을 보안적으로 제어할 수 있다.
예를 들어, 특정 사용자가 요청한 데이터가 그 사용자에게 허용된 데이터인지를 확인하는 등의 인증 작업을 수행할 수 있다.

3. Guard의 장점

보안 강화

  • Guard를 사용하면, 각 요청을 검사하고 필요에 따라 거부함으로써 보안을 강화할 수 있다.

코드 재사용성

  • Guard는 다양한 라우트에서 재사용될 수 있으므로, 인증 로직의 중복을 줄이고 코드의 재사용성을 향상시킨다.

4. Gaurd의 단점

복잡성 증가

  • Guard를 사용하면 보안을 강화할 수 있지만, 동시에 애플리케이션의 복잡성이 증가할 수 있다. Guard를 잘못 구현하면 예상치 못한 보안 이슈를 초래할 수 있으므로, Guard 구현에는 주의가 필요하다.

성능 저하

  • Guard는 모든 요청에 대해 실행되므로, Guard 내부에서 시간이 많이 소요되는 작업을 수행하면 애플리케이션의 성능에 부정적인 영향을 미칠 수 있다. 따라서, Guard 내부의 로직은 최대한 가볍게 유지하는 것이 중요하다.

5. Nest.js의 Guard 사용법

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

위 코드에서 AuthGuard는 CanActivate 인터페이스를 구현하며, canActivate 메소드를 통해 요청을 검사하고 인증 여부를 결정한다.

6. Guard의 동작 원리

Guard는 canActivate 메소드를 통해 요청을 검사한다. 이 메소드는 true 또는 false를 반환하며, false를 반환하면 해당 요청은 거부된다. 이 메소드 내에서는 사용자 인증, 권한 검사 등의 로직을 수행할 수 있다.

7. Guard 적용 방법

Guard는 특정 라우트 핸들러 또는 컨트롤러 전체에 적용할 수 있다. 데코레이터 @UseGuards()를 사용하여 Guard를 적용할 수 있다.

import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './auth.guard';

@Controller('cats')
@UseGuards(AuthGuard)
export class CatsController {
  @Get()
  findAll() {
    // ...
  }
}

8. Guard 커스터마이징

Guard는 CanActivate 인터페이스를 구현하므로 커스터마이징이 가능하다.
예를 들어, 특정 권한이 있는 사용자만 허용하는 Guard, 특정 IP에서 오는 요청만 허용하는 Guard 등을 구현할 수 있다.

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const hasRole = () => user.roles.some((role) => roles.includes(role));
    return user && user.roles && hasRole();
  }
}

위 코드는 RolesGuard라는 새로운 Guard의 예시이며, 이 Guard는 특정 역할(role)을 가진 사용자만 허용한다. 이처럼 Guard를 커스터마이징하면, 보다 세밀한 인증 로직을 구현할 수 있다.

profile
고통 받는 코딩일기

0개의 댓글