NestJS / / 2024. 11. 16. 05:48

NestJS Guard

NestJS Guard에 대한 설명과 예시 정리

Guard는 NestJS에서 요청이 처리되기 전에 실행되는 미들웨어와 유사한 역할을 하는 컴포넌트입니다. 주로 요청을 인증하거나 특정 조건을 확인하여 요청의 허용 여부를 결정하는 데 사용됩니다.

Guard는 다음과 같은 특징을 가집니다:

  1. 클래스 기반: Guard는 클래스이고, @Injectable() 데코레이터로 정의됩니다.
  2. CanActivate 메서드: 모든 Guard는 CanActivate 메서드를 구현해야 하며, 이 메서드에서 요청의 허용 여부를 true 또는 false로 반환합니다.
  3. 의존성 주입 가능: Guard 클래스는 의존성을 주입받아 사용할 수 있습니다.
  4. 컨트롤러 또는 라우트에 적용: Guard는 특정 컨트롤러나 라우트에 적용할 수 있습니다.

코드 예제를 통한 설명

1. BearerTokenGuard

  • BearerTokenGuard는 기본적인 인증 Guard로, 요청 헤더에 포함된 Bearer 토큰을 추출하고 유효성을 검증합니다.

작동 방식:

  1. authorization 헤더에서 토큰 값을 추출합니다.
  2. 토큰을 검증(authService.verifyToken)하여 유효성을 확인합니다.
  3. 검증 결과에서 사용자 정보를 조회(usersService.getUserByEmail)하고, 요청 객체(req)에 사용자와 토큰 정보를 추가합니다.

코드 핵심:

async canActivate(context: ExecutionContext): Promise<boolean> {
    const req = context.switchToHttp().getRequest();
    const rawToken = req.headers['authorization'];

    if (!rawToken) {
        throw new UnauthorizedException('토큰이 없습니다!');
    }

    const token = this.authService.extractTokenFromHeader(rawToken, true);
    const result = await this.authService.verifyToken(token);
    const user = await this.usersService.getUserByEmail(result.email);

    req.user = user;
    req.token = token;
    req.tokenType = result.type;

    return true;
}

2. AccessTokenGuard

  • AccessTokenGuardBearerTokenGuard를 상속받아 Access Token만 허용하도록 확장되었습니다.

작동 방식:

  1. 상속받은 canActivate 메서드를 호출하여 기본 Bearer 토큰 인증을 수행합니다.
  2. 요청 객체에 추가된 tokenTypeaccess인지 확인합니다.
  3. Access Token이 아닌 경우 예외를 발생시킵니다.

코드 핵심:

if (req.tokenType !== 'access') {
    throw new UnauthorizedException('Access Token이 아닙니다.');
}

3. RefreshTokenGuard

  • RefreshTokenGuardBearerTokenGuard를 상속받아 Refresh Token만 허용하도록 확장되었습니다.

작동 방식:

  1. 상속받은 canActivate 메서드를 호출하여 기본 Bearer 토큰 인증을 수행합니다.
  2. 요청 객체에 추가된 tokenTyperefresh인지 확인합니다.
  3. Refresh Token이 아닌 경우 예외를 발생시킵니다.

코드 핵심:

if (req.tokenType !== 'refresh') {
    throw new UnauthorizedException('Refresh Token이 아닙니다.');
}

Guard 적용 예시

postPosts 메서드에서 AccessTokenGuard를 사용한 예시를 보면 Guard가 어떻게 사용되는지 알 수 있습니다.

코드:

@Post()
@UseGuards(AccessTokenGuard)
postPosts(
    @User() user: UsersModel,
    @Body('title') title: string,
    @Body('content') content: string,
) {
    return this.postsService.createPost(user.id, title, content);
}

동작 과정:

  1. 요청이 postPosts 메서드로 들어오면 AccessTokenGuard가 실행됩니다.
  2. AccessTokenGuard는 Bearer 토큰을 검증하고, 토큰 유형이 access인지 확인합니다.
  3. 검증을 통과한 경우, 요청은 컨트롤러의 핸들러로 전달됩니다.
  4. @User() 데코레이터를 통해 req.user에 저장된 사용자 정보를 가져옵니다.
  5. 사용자 정보와 제목, 내용을 postsService.createPost에 전달합니다.

Guard의 계층 구조와 역할

1. BearerTokenGuard:

  • 토큰을 검증하고 사용자 정보를 요청 객체에 저장합니다.
  • 토큰 유형(access, refresh)에 대한 구분은 하지 않습니다.

2. AccessTokenGuardRefreshTokenGuard:

  • BearerTokenGuard를 확장하여 각각 Access Token과 Refresh Token만 허용하도록 세분화합니다.
  • 특정 토큰 유형만 허용하므로 보안성이 강화됩니다.

Guard의 활용 장점

  1. 코드 재사용성: 여러 컨트롤러와 라우트에서 동일한 인증 로직을 재사용할 수 있습니다.
  2. 모듈화: 인증과 관련된 로직을 Guard로 분리하여 코드의 가독성과 유지보수성을 높입니다.
  3. 유연성: Guard를 계층적으로 설계하여 다양한 인증 및 검증 로직을 구현할 수 있습니다.

이 코드에서 Guard는 토큰 기반 인증 시스템에서 핵심적인 역할을 하며, 역할에 따라 세분화된 Guard를 통해 보안성을 높이고 코드의 재사용성을 극대화하고 있습니다.

'NestJS' 카테고리의 다른 글

NestJS DTO,Validation  (0) 2024.11.18
NestJS 데코레이터  (0) 2024.11.16
NestJS 핫리로드 트러블슈팅  (1) 2024.11.16
NestJS Pipe  (0) 2024.11.15
회원가입로직  (2) 2024.11.14
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유