프로그래밍/Nest.js

JWT 인증: Nest.js에서의 안전한 사용자 인증 및 권한 부여

shimdh 2025. 3. 16. 20:45
728x90

현대 웹 애플리케이션에서 사용자 인증과 권한 부여는 필수적인 요소입니다. 사용자 데이터의 안전성과 시스템의 무결성을 보장하기 위해서는 효과적인 인증 메커니즘이 필요합니다. 이번 포스트에서는 Nest.js 프레임워크를 활용하여 JSON Web Token(JWT)을 통한 안전하고 효율적인 인증 및 권한 부여 메커니즘을 구현하는 방법에 대해 알아보겠습니다.

JWT란 무엇인가?

JWT는 JSON 형식으로 인코딩된 정보를 안전하게 전송하기 위한 표준입니다. 주로 클라이언트와 서버 간의 정보 교환에 사용되며, 다음과 같은 세 가지 주요 구성 요소로 이루어져 있습니다:

  1. 헤더(Header): 토큰의 유형과 사용된 해싱 알고리즘을 정의합니다.
  2. 페이로드(Payload): 사용자 정보, 권한, 만료 시간 등 다양한 메타데이터를 포함합니다.
  3. 서명(Signature): 헤더와 페이로드를 결합한 후 비밀 키로 서명하여 데이터의 무결성을 보장합니다.

JWT 인증의 흐름

JWT 인증 과정은 다음과 같은 단계로 이루어집니다:

  1. 사용자 로그인:

    • 사용자가 로그인 요청을 보내면, 서버는 자격 증명을 확인합니다.
    • 인증이 성공하면, 서버는 JWT를 생성하여 클라이언트에게 반환합니다.
  2. 클라이언트 저장:

    • 클라이언트는 받은 JWT를 로컬 스토리지나 쿠키에 저장합니다.
  3. API 요청 시 JWT 전송:

    • 클라이언트는 API 요청 시 Authorization 헤더에 JWT를 포함하여 서버에 요청합니다.
  4. 서버 검증:

    • 서버는 전달받은 JWT를 검증하고, 유효성 여부에 따라 접근을 허용하거나 거부합니다.

Nest.js에서의 JWT 구현 예시

Nest.js에서는 @nestjs/jwt 패키지를 활용하여 쉽게 JWT 기반 인증 기능을 구현할 수 있습니다. 다음은 그 과정에 대한 단계별 설명입니다:

1. 패키지 설치

먼저, 필요한 패키지를 설치합니다.

npm install @nestjs/jwt passport-jwt

2. 모듈 설정

JWT 모듈을 설정하여 비밀 키와 만료 시간을 정의합니다.

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    JwtModule.register({
      secret: 'your_secret_key', // 비밀 키
      signOptions: { expiresIn: '60s' }, // 만료 시간 설정
    }),
  ],
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}

3. 인증 서비스 작성

사용자가 로그인할 때 JWT를 생성하는 로직을 구현합니다.

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(private jwtService: JwtService) {}

  async login(userId: string) {
    const payload = { userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

4. 전략 설정 (JWT 전략)

서버가 클라이언트로부터 받은 JWT를 검증하는 방법을 정의합니다.

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: 'your_secret_key',
    });
  }

  async validate(payload) {
    return { userId: payload.userId }; // 유저 정보를 반환
  }
}

5. 컨트롤러에서 보호된 라우팅 추가하기

보호된 리소스에 접근하기 위해 컨트롤러에서 인증 가드를 설정합니다.

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

@Controller('protected')
export class ProtectedController {

  @UseGuards(AuthGuard('jwt'))
  @Get()
  getProtectedResource() {
    return "This is a protected resource";
  }
}

요약

  • JWT 인증은 웹 애플리케이션에서 사용자 식별과 권한 관리를 위해 널리 사용되는 방법입니다.
  • Nest.js에서는 간단하게 모듈화된 구조로 이를 구현할 수 있으며, 필요에 따라 다양한 커스터마이징도 가능합니다.
  • 위 예제를 통해 기본적인 흐름과 코드 구조를 이해하고 적용해볼 수 있으며, 이를 바탕으로 더 복잡한 인증 시스템으로 발전시킬 수 있습니다.

이러한 방식으로 Nest.js 내에서 효과적으로 사용자 인증 및 권한 부여 기능을 구현할 수 있으므로, 실무에서도 많이 활용되고 있습니다.

728x90