[NestJS 인증 흐름] Jwt 토큰 기반 인증 요청 흐름 정리

2025. 5. 22. 13:05·Nest.js
728x90
반응형

[NestJS 인증 흐름] Jwt 토큰 기반 인증 요청 흐름 정리

NestJS는 Spring Security처럼 정교한 요청 처리 체인을 갖고 있으며,
Middleware → Guard → Interceptor → Pipe → Controller → Service → Response
의 구조를 통해 요청을 세밀하게 통제할 수 있다. 이 글에서는 Spring Security의 구성요소들과 NestJS의 흐름이 어떻게 대응되는지를 정리하고, JWT 기반 인증 요청이 들어왔을 때 NestJS 내부에서 어떤 순서로 로직이 실행되는지를 Spring 경험자의 시선에서 상세히 정리해본다.


Spring Security와 NestJS의 대응 표

Spring Security 구성 NestJS 대응 주요 역할
Filter Middleware Express 수준의 요청 전처리
SecurityContextHolder Guard (→ request.user 주입) 인증 정보 주입, 인가 검증
HandlerInterceptor Interceptor 요청/응답 가로채기, 로깅 등
@ControllerAdvice + @ExceptionHandler ExceptionFilter 글로벌 예외 포맷 처리
@Valid, @RequestBody Pipe, ValidationPipe DTO 변환 및 유효성 검증

요청 흐름 개요

클라이언트가 Authorization: Bearer <JWT> 헤더를 포함한 API 요청을 보냈을 때, NestJS 내부에서 수행되는 순서를 단계별로 분해하면 다음과 같다:

Request
  ↓
[Middleware]
  ↓
[Guards] - JwtAuthGuard
  ↓
[Interceptors - Before]
  ↓
[Pipes] - ValidationPipe
  ↓
[Controller Handler] - @Get('/me')
  ↓
[Interceptors - After]
  ↓
Response
※ 오류 발생 시 어느 단계에서든 ExceptionFilter로 이동

주요 흐름 설명 및 코드 예시

1. 클라이언트 요청
GET /api/me HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
2. JwtAuthGuard 실행

JwtAuthGuard는 @UseGuards(JwtAuthGuard) 또는 app.useGlobalGuards()를 통해 등록되어 요청 전에 실행된다. 본인은 글로벌 가드에 등록해 전역적으로 실행하도록 설정하고, 인증이 필요하지 않은 api는 별도 데코레이터를 만들처 처리했다.

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
3. JwtStrategy.validate(payload)
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly userRepository: UserRepository) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'your_jwt_secret',
    });
  }

  async validate(payload: JwtPayload) {
    const user = await this.userRepository.findOne({
      where: { id: payload.sub },
    });

    if (!user) {
      throw new UnauthorizedException('존재하지 않는 사용자입니다.');
    }

    return {
      id: user.id,
      userName: user.userName,
      role: user.role,
    };
  }
}

이 validate()에서 반환된 객체는 request.user로 주입된다.

4. Controller에서 사용자 정보 접근
@Get('/me')
async getProfile(@CurrentUser() user: User) {
  return this.userService.getProfile(user.id);
}
5. @CurrentUser() 커스텀 데코레이터
export const CurrentUser = createParamDecorator(
  (data, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
6. 서비스 레이어에서 사용자 데이터 처리
async getProfile(userId: string) {
  return await this.userRepository.findOne({ where: { id: userId } });
}

  1. 테스트/설정 실행 방법, 환경 설정 방법 포함
  • passport, @nestjs/passport, passport-jwt, jsonwebtoken 등의 패키지가 필요하며 JwtModule.register()로 시크릿 키를 등록해야 한다.
  • 테스트 시 Authorization 헤더에 유효한 JWT를 포함해야 한다.
  • 인터셉터, 파이프, 필터는 app.useGlobal...() 방식으로 전역 등록하거나 데코레이터 방식으로 라우트에 적용할 수 있다.

  1. 표/정리로 중요한 부분 요약
구성 요소 NestJS 위치 실행 시점 주요 역할
Middleware Express 수준 가장 먼저 헤더 파싱 등
Guard AuthGuard 요청 전 인증/인가 판단, request.user 주입
Interceptor Nest 인터셉터 핸들러 전후 로깅, 응답 포맷 처리 등
Pipe DTO 위 요청 바디/파라미터 변환 및 검증
Controller 라우터 핸들러 실제 요청 처리 서비스 호출, 응답 리턴
Exception Filter 예외 발생 시 모든 단계 에러 응답 처리

✅ 최종 정리

  • NestJS의 요청 처리 흐름은 Spring Security FilterChain + Interceptor + AOP 구조와 매우 유사하다.
  • JwtAuthGuard를 통해 JWT 토큰을 파싱하고, JwtStrategy에서 유저를 조회한 뒤, 이를 request.user에 주입한다.
  • 컨트롤러에서는 이를 커스텀 데코레이터(@CurrentUser)를 통해 간편하게 받아 사용할 수 있다.
  • Interceptor와 Pipe는 로직 흐름의 앞뒤를 정리해주며, Exception Filter는 어느 지점에서든 발생한 예외를 일관된 포맷으로 처리할 수 있게 돕는다.

Spring 경험자에게 NestJS의 흐름은 익숙하면서도 구조적으로 더 모듈화된 느낌을 준다. 각 단계를 잘 조합하면 가독성 높고 유연한 인증 흐름을 만들 수 있다.

728x90
반응형

'Nest.js' 카테고리의 다른 글

[NestJS - 트러블 슈팅] 몽고 DB replicaSet 없이는 트랜잭션 불가능  (4) 2025.06.19
NestJS 엔티티, 왜 다 public이야? – Spring 개발자의 궁금증 해결  (1) 2025.05.25
[NestJS 응답/요청 변환기] 내부 camelCase, 외부 snake_case 통일하기  (0) 2025.05.22
[Nest.js] 제로베이스에서 1주일, 실전까지 반나절  (1) 2025.05.22
Nest.js 개발에 필요한 주요 CLI 명령어와 활용법  (1) 2025.05.22
'Nest.js' 카테고리의 다른 글
  • [NestJS - 트러블 슈팅] 몽고 DB replicaSet 없이는 트랜잭션 불가능
  • NestJS 엔티티, 왜 다 public이야? – Spring 개발자의 궁금증 해결
  • [NestJS 응답/요청 변환기] 내부 camelCase, 외부 snake_case 통일하기
  • [Nest.js] 제로베이스에서 1주일, 실전까지 반나절
highgarden
highgarden
커밋 하나하나가 쌓여 커다란 정원이 되는 중입니다. 하루하루 정성껏 심어가는 중 https://github.com/highgarden7
  • highgarden
    커밋심는 정원
    highgarden
  • 전체
    오늘
    어제
    • 분류 전체보기 (37)
      • ai (1)
      • devops (2)
      • Nest.js (14)
      • linux (14)
      • 네트워크 (6)
      • git (0)
      • aws (0)
      • docker (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    nestjs
    Linux
    githib action
    Chat GPT
    E2E
    springboot
    IP
    Java
    네트워크
    vercel
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
highgarden
[NestJS 인증 흐름] Jwt 토큰 기반 인증 요청 흐름 정리
상단으로

티스토리툴바