프로그래밍/Nest.js

커스텀 가드 구현으로 애플리케이션 보안 강화하기

shimdh 2025. 3. 21. 09:05
728x90

애플리케이션의 보안은 현대 소프트웨어 개발에서 가장 중요한 요소 중 하나입니다. 특히, 사용자 인증 및 권한 부여는 모든 애플리케이션에서 필수적으로 고려해야 할 사항입니다. 이번 포스트에서는 Nest.js에서 커스텀 가드를 구현하여 애플리케이션의 보안을 강화하는 방법에 대해 알아보겠습니다.

가드의 개념과 역할

가드는 요청이 처리되기 전에 특정 조건을 검사하여 요청의 흐름을 제어하는 중요한 구성 요소입니다. 가드는 다음과 같은 역할을 수행합니다:

  • 요청 필터링: 클라이언트가 서버에 요청할 때, 해당 요청이 유효한지 확인하는 과정은 매우 중요합니다. 이를 통해 악의적인 요청이나 잘못된 데이터가 서버에 도달하는 것을 방지할 수 있습니다.
  • 인증 및 인가: 사용자가 적절한 자격 증명을 가지고 있는지 또는 특정 리소스에 접근할 수 있는 권한이 있는지를 판단하는 과정은 보안의 핵심입니다. 이 과정에서 사용자의 신원을 확인하고, 그에 따라 적절한 권한을 부여합니다.
  • 흐름 제어: 조건에 따라 다음 미들웨어 또는 핸들러로 진행하거나, 오류 응답을 반환하여 처리를 중단하는 기능은 애플리케이션의 흐름을 관리하는 데 필수적입니다. 이를 통해 예기치 않은 상황에서의 오류를 예방하고, 사용자에게 적절한 피드백을 제공할 수 있습니다.

커스텀 가드 구현

커스텀 가드를 만드는 과정은 비교적 간단하며, 아래 단계들을 통해 진행할 수 있습니다:

  1. 가드 클래스 생성: 새로운 가드 클래스를 생성하여, 해당 클래스에서 필요한 로직을 구현합니다.
  2. CanActivate 인터페이스 구현: 이 인터페이스를 구현함으로써, 가드가 요청을 처리할 수 있는 기능을 갖추게 됩니다.
  3. Guard를 모듈에 등록: 생성한 가드를 Nest.js 모듈에 등록하여, 애플리케이션 전반에서 사용할 수 있도록 설정합니다.

예제 코드

아래는 JWT 기반 인증을 위한 커스텀 가드를 구현하는 예제입니다. 이 코드는 JWT 토큰을 검증하여 사용자의 신원을 확인하고, 요청 객체에 사용자 정보를 추가하는 과정을 보여줍니다.

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class JwtAuthGuard implements CanActivate {
  constructor(private authService: AuthService) {}

  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const token = request.headers.authorization?.split(' ')[1];

    if (!token) {
      return false; // 토큰이 없으면 접근 불가
    }

    try {
      const user = this.authService.validateToken(token); // 토큰 검증
      request.user = user; // 유저 정보를 요청 객체에 추가
      return true;
    } catch (error) {
      return false; // 검증 실패 시 접근 불가
    }
  }
}

위 코드는 JwtAuthGuard라는 이름의 커스텀 가드를 정의합니다. 이 클래스는 CanActivate 인터페이스를 구현하며, canActivate 메서드에서 토큰 검증 로직을 수행합니다. 이를 통해 사용자가 유효한 토큰을 가지고 있는지 확인하고, 그에 따라 요청을 처리할 수 있는 권한을 부여합니다.

모듈 등록 및 사용

커스텀 가드를 생성한 후에는 이를 Nest.js 모듈에서 사용할 수 있도록 등록해야 합니다. 이를 통해 애플리케이션의 다양한 부분에서 이 가드를 활용할 수 있습니다.

import { Module } from '@nestjs/common';
import { AuthModule } from './auth/auth.module';
import { JwtAuthGuard } from './guards/jwt-auth.guard';

@Module({
  imports: [AuthModule],
})
export class AppModule {}

모듈 내에서 글로벌하게 사용할 수도 있고, 특정 컨트롤러나 라우트 핸들러에도 적용 가능합니다. 예를 들어, 특정 엔드포인트에만 적용할 수 있는 방법은 다음과 같습니다.

import { Controller, Get, UseGuards } from '@nestjs/common';

@Controller('protected')
export class ProtectedController {

  @Get()
  @UseGuards(JwtAuthGuard)
  getProtectedResource() {
    return 'This is a protected resource!';
  }
}

위와 같이 @UseGuards() 데코레이터를 사용하여 특정 엔드포인트에만 적용할 수 있습니다. 이를 통해 애플리케이션의 보안을 더욱 강화할 수 있습니다.

요약

  • 가드는 Nest.js 애플리케이션의 보안 강화를 위해 필수적인 요소입니다. 이를 통해 애플리케이션의 요청을 안전하게 관리하고, 사용자에게 적절한 권한을 부여할 수 있습니다.
  • 커스텀 가드는 다양한 비즈니스 요구 사항에 맞춰 쉽게 만들고 관리할 수 있습니다. 이를 통해 각 애플리케이션의 특성에 맞는 보안 정책을 구현할 수 있습니다.
  • 위 예제를 통해 기본적인 JWT 인증 기능을 가진 커스텀 가드를 만드는 방법과 이를 활용하는 방법까지 살펴보았습니다. 이러한 방식으로 자신만의 규칙이나 정책에 맞춘 다양한 종류의 커스텀 가드를 만들어 나갈 수 있습니다. 이를 통해 애플리케이션의 보안을 한층 더 강화할 수 있습니다!
728x90