본문 바로가기

Backend/NestJS

@Controller 데코레이터 위에 @UseGuards()를 선언했을 경우와 메소드에서만 선언했을때 차이점

들어가기 앞서, @UseGuards() 데코레이터란? 

Guard란 permission, roles 등에 따라서 주어진 request가 route handler에 의해 handling이 될지 말지를 결정한다. 

authorization 구현에 많이 쓰이는데, 나 또한 admin에서 특정 권한을 가진 role이 약관 동의 업데이트 시 account 테이블 내의 특정 컬럼들을 한 번에 false로 만드는 작업을 해야했다. 이 작업을 위해 @UseGuards()를 사용해야 했었다. 

 

그러나 여기서 한 가지 놓치고 있었던 점이 있다. 바로 @UseGuards() 데코레이터의 선언 위치였다. 

 

@Controller 데코레이터 위에서 선언했을때와 

@UseGuards(RolesAuthGuard) 
@Controller('admin') 
export class AdminController { ~ }

 

@UseGuards(RolesAuthGuard)를 해당 메소드에서만 사용할 경우 

@Roles('ADMIN') 
@UseGuards(JwtAuthGuard) 
@Put(~)
async getAdmin { ~ }

했을때 착각했던 점이 하나 있다. 바로 @Controller 위에서 @UseGuards()를 사용했을때 @Roles()를 사용하고 있는 메소드에서 걸러져서 @Controller 위에 @UseGuards() 데코레이터를 선언해도 되지 않을까?했던 점이었다. 

 

그러나 그 생각은 아니었다. @Controller()위에 선언했을때 해당 controller.ts 안에 구현된 메소드들에 다@UseGuards(RolesAuthGuard)가 걸려 지갑 로그인조차 되지 않았다. 

 

그래서 생각을 바꾸어, @Roles('ADMIN')을 필요로 하는 메소드에만 @UseGuards(JwtAuthGuard)를 사용하니, 그 메소드를 API 호출했을때 ADMIN role을 가지지 않은 지갑 주소에 대해서는 403 에러(Unauthorized)가 발생하였다. 이로써 원하는 대로 ADMIN role을 가진 지갑만 특정 컬럼이 false로 일괄 변경할 수 있도록 구현할 수 있었다.