NestJS

[NestJS] Global-guard

begong 2024. 11. 17. 22:46
반응형

글로벌 가드

대부분의 엔드포인트를 보호해야 하는 경우 인증 가드를 글로벌 가드로 등록.

  • 어떤 모듈에서든 다음과 같이 등록하면 모든 엔드포인트에 가드가 붙음
providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],

@Public() 데코레이터를 생성하여 글로벌 가드 뚫기

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

  • setMetaData 데코레이터 팩토리 함수를 통해 @Public 데코레이터 생성
  • IS_PUBLIC_KEY는 메타데이터 키로 사용
    • 이 키를 통해 글로벌가드가 경로에 인증을 생략할지 여부를 식별함.

AuthGuard 에서 @public 처리

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

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}

  • authGuard 클래스를 확장하여, 에러처리, 인증논리를 확장할 수 있음.
  • canActivate함수에서 @public 데코레이터가 설정된 경우 해당경로의 인증을 생략하게 함. ⇒ true가 반환되면 생략됨.

참고

  • Request-Scoped Strategy
    • 일반적인 전략과 달리, 각 요청마다 별도의 인스턴스를 생성하는 인증 전략을 뜻함
    • 본적으로 PassportStrategy로 구현된 전략들은 애플리케이션 전체에서 싱글톤으로 동작하지만, RequestScope로 설정하면 각 HTTP 요청마다 독립적인 인스턴스를 생성하여, 요청에 특화된 상태나 의존성을 가질 수 있음
    • 필요성
      • 기본적으로 NestJS에서 @Injectable()로 선언된 서비스나 전략들은 싱글톤으로 동작합니다. 즉, 애플리케이션 내에서 한 번 생성된 인스턴스가 모든 요청에서 공유됩니다. 그러나 인증에 관련된 전략이 매 요청마다 다른 의존성이나 상태가 필요하다면, Request-Scoped Strategy로 설정하여 요청마다 고유한 인스턴스를 생성할 수 있습니다.
반응형