nest js

NestJs Guard에 대해 알아보자

호리둥절 2023. 4. 7. 10:19

Guard란?

guard는 요청의 처리 여부를 결정하는 미들웨어 역할을 합니다. guard는 인증과 권한 부여 등 요청에 대한 검사를 처리하는 데  주로 사용합니다.

 

 

guard는 @nestjs/common의 CanActivate 인터페이스를 확장하는 클래스로 구현됩니다. 이 인터페이스는 canActivate라는 단일 메서드를 정의하며, 이 메서드는 ExecutionContext 객체를 인수로 취하고 요청이 진행되어야 하는지 여부를 나타내는 부울 값을 반환합니다.

 

 

예를 들어, 아래 코드에서는 JWT 토큰을 가져와 인증 여부를 판단하고, 인증되지 않은 요청은 거부합니다.

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(
    private readonly jwtService: JwtService,
    private readonly authService: AuthService,
  ) { }

  async canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest<any>();
    
    //headear에 토큰이 있는지 확인
    const { authorization } = request.headers;
    if (!authorization) {
      throw new UnauthorizedException('액세스 토큰이 필요한 작업입니다.');
    }
    
    //authorization 값을 추출하고 이 값이 bearer로 시작하는지 검사
    const isBearer = authorization.startsWith('Bearer');
    if (!isBearer) {
      throw new UnauthorizedException('Bearer 토큰이 아닙니다.');
    }

    const accessToken = authorization.split(' ').pop();
    if (!accessToken) {
      throw new UnauthorizedException('토큰을 찾을 수 없습니다.');
    }

    try {
    //토큰 검증 및 토큰에서 추출된 정보 얻어오기
      const payload = await this.jwtService.verifyAsync(accessToken);
      
      //id가 존재하는 id인지 검증
      const user = await this.authService.findById(payload.id);
      if (!user) {
        throw new UnauthorizedException('사용할 수 없는 토큰입니다.');
      }
      //존재 한다면 user와 role 변수에 저장
      request.user = user;
      request.role = payload.role;
    } catch {
      throw new UnauthorizedException('사용할 수 없는 토큰 입니다.');
    }

//모든 작업이 완료되면 true 만약 반환값이 false이면 요청처리 중단
    return true;
  }
}

 

만들어진 AuthGuard를 사용하는법은 이와 같습니다

 // @Get() 데코레이터가 있는 핸들러 메서드에 AuthGuard를 적용
  @Get()
  @UseGuards(AuthGuard)
  async findOne() {
    // 핸들러 메서드의 로직
  }

 

위의 코드에서 @UseGuards() 데코레이터 안에 AuthGuard 클래스를 전달하여 findOne() 메서드에 AuthGuard가 적용됩니다. 이제 클라이언트가 엔드포인트로 GET 요청을 보내면 AuthGuard가 먼저 실행되어 요청이 유효한지 확인하고, 유효하지 않은 경우 401 Unauthorized 응답을 반환합니다.