개발-사용기/Nestjs

nestjs - Role Guard 구현

mouuaw 2021. 8. 12. 22:04

nestjs를 사용하면서 회원의 Role을 기준으로 api를 제공하는 로직을 구현했다.

role guard 구현은 공식 홈페이지에도 예제가 있지만 내가 필요로 하는 guard의 형태는 다음과 같았다.

 

1. Controller 전체에 적용되는 Guard

2. Api에 Role을 명시할 경우, 명시된 Role을 기준으로 검사를 하는 Guard

 

한마디로 Controller 전체에 기본적인 Role을 지정해놓고, 특정 Api에서는 다른 기준의 Role을 적용시키고 싶었다.

 

구글링 결과 내가 원하는 Guard는 mixin 함수를 통해 구현이 가능했다.

 

1. mixin을 통한 Guard 구현

 

위의 코드를 RoleGuard 함수 안에 RoleGuardMixin이라는 클래스를 만들어서 mixin함수를 통해 Guard를 리턴시키는 함수다.

 

왜 이런 형태가 되었는가 하면, 가드에 적용할 Role의 목록을 Controller 부분에서 사용 목적에 맞게 입력시킬 수 있기 때문에 필요에 따라 유연하게 사용 가능하다.

 

 

 

2. SetMetadata를 통한 api 단위 Role 적용

nestjs는 SetMetadata를 통해 request 객체에 추가적인 데이터 전달이 가능하다.

 

-- api에서 선언

-- guard에서 reflector를 통한 metadata 접근 

여기서 globalRoleList는 controller에서 넘어온 roleList 를 의미하고 localRoleList는 api에서 넘어온 roleList를 의미한다.

로직을 살펴보면 localRoleList가 배열로 넘어오면 localRoleList를 사용하고, 그 외의 경우엔 globalRoleList를 사용하게 된다.

 

3. setMetadata를 편하게 쓰기위한 Role decorator 생성

 

Role decorator 는 공식문서에 있는 예제(https://docs.nestjs.com/guards)를 그대로 가져다 썻다.

 

4. 사용부

controller에 @UseGuards 부분을 보면 RoleGuard를 사용하면서 api에 접근 가능한 role목록을 전달해주고 있다.

 

그리고 memberApply api 부분은 관리자 권한만 요청이 가능하도록 @Roles 데코레이션을 통해 Manager, Owner 만 요청 가능하도록 권한을 제한하고 있다. 

이 경우 Manager, Owner가 localRoleList가 되어 해당 api는 roleGuard가 다르게 적용될 것이다.