ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Nest.js, Guard, Save request] Guard를 활용한 엔드포인트 보호
    Back-end 2021. 12. 13. 15:55

    안녕하세요! 오늘은 프로젝트에서 허용되지 않은 접근에 대한 자원 request를 막을 수 있는 nest.js guard에 대해서 알아보도록 하겠습니다! 로그인을 한 유저만 엔드포인트에서 자원을 요청할 수 있는 작업을 해야할 때 우리는 이 nest.js의 guard를 사용할 수 있습니다.

     

    미들웨어로도 처리해도 충분하지 않나요?

    가드와 미들웨어의 차이는 실행 시기에 있습니다. 우선 미들웨어는 next() 함수를 호출한 후 어떠한 핸들러가 실행될 지 알 수 없습니다. 반면 가드 ExecutionContext 인스턴스에 액세스할 수 있으므로 다음에 실행될 작업을 정확히 알고 있습니다. request와 response의 정확한 지점에 우리는 이 Guard를 삽입하여, 요청에 대한 거부, 혹은 승인을 할 수 있는 것이죠. 즉, 가드는 미들웨어 바로 이후에 실행되어 그 요청을 가로채 2차 인증을 하는 것입니다.

     

    우선 공식 문서의 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);
      }
    }

    https://docs.nestjs.kr/guards

     

    네스트JS 한국어 매뉴얼 사이트

    네스트JS 한국, 네스트JS Korea 한국어 매뉴얼

    docs.nestjs.kr

     

    모든 가드는 canActivate 함수를 구현해야 합니다. canActivate는 요청 여부에 대한 값을 true, false로 반환해야 합니다. 만약 true가 리턴된다면 우리는 이 request를 통과시키고 그렇지 않다면 request를 통과시키지 않을 것 입니다.

     

    코드를 살펴보면, request에 대한 정보를 받은 뒤, 이 request에 대한 (작성자의 의도에 의한)또 하나의 request 통과 방식을 validateRequest 함수를 통해 정의할 것입니다. 그리고 그 함수에 대한 로직에 부합하는 request라면 guard는 해당 request를 통과시킬 것이고, 그렇지 않다면 forbidden resource로 클라이언트에게 화답할 것입니다 👊🏻

     

    canActivate 정의

    context의 타입은 ExecutionContext로 상속되어 있습니다. 이 룰을 확인하고 context를 canActive를 통해 받을 수 있을 것입니다.

     

     

    @UseGuards(AuthGuard)

    Guard의 사용은 graphql resolver에 존재하는 쿼리나 뮤테이션, 서브스크립션 등의 요청에 선언하면 되고 이 것은 @nestjs/common 라이브러리를 통해 공유됩니다.  UseGuards의 스코프 내에 선언된 요청들은 선언한 AuthGuard에 의해 보호될 것입니다 👋🏻

     

     

     

    오늘은 nest.js의 Guard에 대해 공부하고 정리해보았습니다. 필요한 request만 받고, 이에 대해서만 자원을 사용해야 할 때 사용할 수 있는 nest.js의 훌륭한 보안 수단인 것 같습니다. 감사합니다 👀

    댓글

sangjun's blog