TIL

23/12/25 TIL __ nestJs 에서 RolesGuard

GABOJOK 2023. 12. 25. 23:57

 

 

 

 

강의를 들으며 roles.guard.ts 파일에 작성된 코드가 이해가 안되어 하나하나 뜯어봤다. 

오늘은 이 기록을 공유 해보려 한다. 

 

 

 

 

roles.guard.ts

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { Role } from 'src/user/types/userRole.type';

@Injectable()
export class RolesGuard extends AuthGuard('jwt') implements CanActivate {
  constructor(private reflector: Reflector) {
    super();
  }

  async canActivate(context: ExecutionContext) {
    //로그인이 되어 있는 유저인가 확인.(req가 있는지 파악 하면서 확인.)
    const authenticated = await super.canActivate(context);
    if (!authenticated) {
      return false;
    }

    //핸들러에 걸려있는 권한 체크
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>('roles', [
      context.getHandler(), //req, res객체 읽음.
      context.getClass(), //클래스에 설정된 데코레이터, 메타데이터를 읽음.
    ]);
    console.log('롤가드 리콰이어롤즈 확인', requiredRoles);

    //권한이 안걸려 있더라고 볼 수 있도록 true 통과시킬거라는말.
    if (!requiredRoles) {
      return true;
    }

    //req.user.role과 비교해서 true인 경우 이 미들웨어 통과.
    const { user } = context.switchToHttp().getRequest();
    console.log('롤가드 유저 확인', user);
    return requiredRoles.some((role) => {
      console.log('롤가드 리콰이어롤즈 확인2', user.role === role);
      return user.role === role;
    });
  }
}

 

 

 

그럼 이게 언제 동작할까?

아래는 service.ts 파일의 일부분 이다.

 

@UseGuards(RolesGuard)  //얘를 만나면서 roles.guard.ts 파일 동작
@Controller('team')
export class TeamController {
  constructor(private readonly teamService: TeamService) {}

  @Roles(Role.Admin) //얘를 만나면서 roles.guard.ts 파일 동작
  @Delete(':id')
  async delete(@Param('id') id: number) {
    await this.teamService.delete(id);
  }
}

 

 

 

플로우는 이렇다. 

 

  1. UseGuards(RolesGuard)를 만나면 roles.guard.ts 파일을 읽기 시작한다. 
  2. 권한이 따로 걸려있지 않은 상황이기에 if(!requireRoles) 에서 걸려 끝나게 된다. 
  3. 다시 service.ts 파일로 돌아와서 읽기 시작하는데, 현재 받은 요청에 걸린 @Roles(Role.Admin) 을 만난다. 
  4. 권한이 Admin인 사람에게만 통과시키기 위한 장치이다. 
  5. 이 장치를 만남으로 다시 roles.guard.ts를 만난다.
  6. 이번에는  console.log('롤가드 유저 확인', user) 라고 적혀있는 곳에 현재 로그인 된 유저의 권한이 출력되고, 
  7. console.log('롤가드 리콰이어롤즈 확인2', role) 에는 허용하겠다고 선언한 권한. 즉 Admin이 출력된다. 
  8. 이를 비교해 같다면 true를 리턴함으로 통과, 아니라면 false를 리턴한다. 

 

 

 

처음보는 함수들이 많이 나와 이 파일을 이해하기 더 어려웠던 것 같다. 

그렇지만 하나하나 찾아보며 이해하니 이제 이해 된당 

아주 유용하게 쓰일 것 같다.