자바스크립트로 작성된 NestJS API 서버의 사용자 인증 방법

NestJS는 Node.js를 기반으로 하는 프레임워크로, 자바스크립트로 서버 애플리케이션을 구축할 수 있도록 도와줍니다. 이번 글에서는 NestJS API 서버에서 사용자 인증을 구현하는 방법에 대해 알아보겠습니다.

Passport.js와 JWT를 활용한 사용자 인증

NestJS에서 사용자 인증을 위해 가장 많이 사용되는 방법은 Passport.js와 JWT(Json Web Token)입니다. 이 둘을 함께 사용하여 안전하고 효율적인 사용자 인증 시스템을 구축할 수 있습니다.

1. Passport.js 설치

먼저 Passport.js를 설치해야 합니다. 아래 명령어를 사용하여 Passport.js를 프로젝트에 추가합니다.

npm install passport passport-local @nestjs/passport

2. 로컬 전략(Local Strategy) 구현

로컬 전략은 사용자의 아이디와 비밀번호를 이용하여 인증하는 방법입니다. 먼저 LocalStrategy라는 클래스를 생성합니다. 이 클래스는 PassportStrategy를 확장하고 validate() 메서드를 구현해야 합니다.

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

3. AuthService 생성

인증 서비스(AuthService) 클래스를 생성하여 실제로 사용자를 인증하는 로직을 구현해야 합니다. 이 클래스는 validateUser() 메서드를 구현해야 합니다.

@Injectable()
export class AuthService {
  async validateUser(username: string, password: string): Promise<any> {
    // 사용자 아이디와 비밀번호를 확인한 후 유저 객체 반환
  }
}

4. AuthModule 설정

AuthModule을 생성하고 Passport 모듈과 LocalStrategy, AuthService를 설정해야 합니다. 아래 코드는 AuthModule의 구성 예시입니다.

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'local' }),
    // 다른 모듈 import
  ],
  controllers: [AuthController],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}

5. JWT 토큰 생성과 검증

JWT를 사용하여 사용자의 인증 상태를 추적합니다. 토큰을 생성하고 검증하는 로직은 AuthModule에서 구현됩니다.

먼저 JWT 관련 라이브러리를 설치합니다.

npm install @nestjs/jwt passport-jwt

그리고 JWT 모듈과 JwtStrategy를 AuthModule에 추가합니다.

import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    JwtModule.register({
      secret: 'secretKey',
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}

6. JwtStrategy 구현

JwtStrategy는 JWT 토큰의 유효성을 검사하는 역할을 합니다. 다음과 같이 JwtStrategy 클래스를 생성하고 유효성 검사를 구현합니다.

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

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

  async validate(payload: any) {
    // 유저 정보를 조회하고, 없을 경우 예외 처리
  }
}

7. 컨트롤러에서 인증 사용

마지막으로, 사용자 인증을 사용하는 컨트롤러에서 AuthGuard()를 적용합니다. 아래 코드는 인증이 필요한 라우트에 AuthGuard()를 적용하는 방법입니다.

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

@Controller('users')
export class UserController {
  @Get()
  @UseGuards(AuthGuard())
  getUsers() {
    // 인증된 사용자만 접근 가능한 로직
  }
}

이제 NestJS API 서버에서 사용자 인증을 구현하는 방법을 알아보았습니다. Passport.js와 JWT를 조합하여 안전하고 효율적인 인증 시스템을 구축할 수 있습니다.

참고 자료: