프로그래밍/Nest.js

Nest.js에서의 가드와 인터셉터: 비동기 처리의 중요성

shimdh 2025. 3. 23. 15:35
728x90

Nest.js는 현대 웹 애플리케이션 개발에 있어 강력한 프레임워크로 자리 잡고 있으며, 그 중에서도 가드(Guard)와 인터셉터(Interceptor)는 요청과 응답 흐름을 제어하는 데 필수적인 요소입니다. 이 두 가지 구성 요소는 각각의 고유한 목적을 가지고 있지만, 함께 활용함으로써 더욱 강력하고 유연한 기능성을 제공합니다. 이번 포스트에서는 가드와 인터셉터의 개념, 비동기 처리의 중요성, 그리고 실제 예시를 통해 이들의 활용 방법을 살펴보겠습니다.

1. 가드 (Guard)

가드는 요청이 핸들러에 도달하기 전에 실행되는 미들웨어로, 주로 인증이나 권한 부여와 같은 보안 관련 작업에 사용됩니다. 가드는 기본적으로 boolean 값을 반환하며, true일 경우 요청이 계속 진행되고 false일 경우 요청이 차단됩니다. 이러한 기능은 애플리케이션의 보안을 강화하는 데 중요한 역할을 합니다.

비동기 가드

비동기 가드는 Promise 또는 Observable을 반환하여 비동기 작업을 수행할 수 있는 기능을 제공합니다. 예를 들어, 데이터베이스에서 사용자 정보를 조회하거나 외부 API를 호출한 후 그 결과에 따라 접근 권한을 결정하는 등의 작업을 수행할 수 있습니다. 이는 특히 사용자 역할이나 권한을 동적으로 확인해야 할 때 유용합니다.

실제 예시

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    const user = request.user;

    // 비동기로 역할 확인 (예: 데이터베이스 쿼리)
    return this.validateUserRole(user);
  }

  async validateUserRole(user): Promise<boolean> {
    // 여기서 DB나 외부 API를 호출해 사용자 역할 검증
    return user.role === 'admin'; // 예시 조건
  }
}

위의 예시에서 RolesGuard는 사용자의 역할을 비동기로 확인하여 요청을 허용할지 여부를 결정합니다. 이처럼 비동기 가드는 복잡한 인증 로직을 처리하는 데 매우 유용합니다.

2. 인터셉터 (Interceptor)

인터셉터는 메서드를 감싸서 추가적인 로직을 수행할 수 있는 기능으로, 주로 응답 변환이나 로깅, 입력값 변환과 같은 전처리 작업에 사용됩니다. 이를 통해 개발자는 요청과 응답의 흐름을 더욱 세밀하게 제어할 수 있습니다.

비동기 인터셉터

비동기 인터셉터는 Promise 또는 Observable을 반환하여 비동기로 동작합니다. 이는 네트워크 요청 후 데이터를 조작하거나 로그 기록 등을 위한 유용한 방법으로, 애플리케이션의 성능을 최적화하는 데 기여할 수 있습니다.

실제 예시

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    return next.handle().pipe(
      tap(() => console.log('After...')),
      // 여기에 추가적인 처리가 가능하다.
      map(data => ({ ...data, extraData: 'This is additional data' })) // 응답 수정
    );
  }
}

위의 LoggingInterceptor는 요청이 처리되기 전과 후에 로그를 기록하며, 응답 데이터를 수정하는 기능을 제공합니다. 이러한 방식으로 인터셉터는 요청과 응답의 흐름을 더욱 유연하게 제어할 수 있습니다.

결론

비동기 가드와 인터셉터는 Nest.js 애플리케이션의 세밀한 제어를 가능하게 하여, 보안 강화와 성능 최적화를 동시에 달성할 수 있도록 돕습니다. 이러한 기능을 통해 복잡한 요구 사항도 쉽게 처리할 수 있으며, 코드의 재사용성과 유지보수성을 높이고 개발 효율성을 증가시킬 수 있습니다. 따라서 고급 모듈 관리 및 프로바이더와 함께 이 두 가지 요소를 적절히 설계하고 구현하는 것이 매우 중요합니다. 이를 통해 개발자는 더욱 견고하고 확장 가능한 애플리케이션을 구축할 수 있습니다.

728x90