728x90

1. 🔑 인증 시스템의 핵심 구성 요소
NestJS에서 안전하고 확장 가능한 인증 시스템을 구축하기 위해 주로 JWT (JSON Web Token) 표준과 Passport 모듈을 사용합니다.
- Passport: Node.js의 미들웨어로, 다양한 인증 메커니즘을 플러그인 형태로 지원하는 프레임워크입니다. NestJS는 @nestjs/passport 모듈을 통해 이를 통합합니다.
- JWT: 사용자 정보를 담고 있는 서명된 토큰입니다. 이 토큰은 클라이언트에 저장되며, 이후 요청 시 서버에 전송되어 사용자 인증에 사용됩니다.
- Guard: JWT의 유효성을 검사하고 사용자에게 접근 권한이 있는지 확인하는 NestJS의 핵심 컴포넌트입니다.
2. 📝 Passport Strategy (전략) 정의
Passport는 인증 방식을 전략(Strategy)이라고 부릅니다. 일반적인 인증 과정에는 두 가지 주요 전략이 사용됩니다.
2.1. Local Strategy (로그인)
사용자 이름(이메일)과 비밀번호를 검증하여 사용자를 인증하는 전략입니다. 이는 로그인 시점에만 사용됩니다.
- 사용자 검증: 클라이언트가 전송한 자격 증명(Credential)을 데이터베이스에 저장된 값과 비교합니다.
- 토큰 생성: 검증에 성공하면, AuthService를 통해 사용자 정보를 담은 JWT를 생성합니다.
// local.strategy.ts (예시)
import { Strategy } from 'passport-local';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
// 💡 Passport가 호출하는 검증 함수
async validate(email: string, pass: string): Promise<any> {
const user = await this.authService.validateUser(email, pass);
if (!user) {
throw new UnauthorizedException('아이디 또는 비밀번호가 일치하지 않습니다.');
}
// 💡 JWT Payload에 담길 사용자 정보 반환
return user;
}
}
728x90
2.2. JWT Strategy (토큰 검증)
로그인 후 발생하는 모든 요청에 대해 JWT 토큰을 검증하는 전략입니다.
- 토큰 추출: 요청 헤더에서 JWT를 추출합니다.
- 서명 검증: JWT의 서명(Signature)이 유효한지 확인합니다.
- Payload 반환: 유효성 검증이 완료되면, 토큰의 내용(Payload)을 추출하여 요청 객체에 담습니다.
// jwt.strategy.ts (예시)
import { Strategy, ExtractJwt } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), // 💡 Bearer 토큰에서 JWT 추출
secretOrKey: process.env.JWT_SECRET, // JWT 서명 검증 키
});
}
// 💡 토큰이 유효할 때 호출됨
async validate(payload: any) {
// 💡 payload를 request.user에 주입하여 컨트롤러에서 사용 가능하게 함
return { userId: payload.sub, email: payload.email };
}
}
3. 🛡️ Guard를 이용한 라우트 보호
Passport 전략이 정의되면, 이를 NestJS의 Guard로 변환하여 라우트에 적용합니다.
3.1. Local Guard (로그인 시점)
로그인 요청이 들어오면 AuthGuard('local')이 LocalStrategy를 호출합니다.
// auth.controller.ts
import { Post, UseGuards, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('auth')
export class AuthController {
// 💡 LocalStrategy를 실행하도록 지시하는 Guard
@UseGuards(AuthGuard('local'))
@Post('login')
async login(@Request() req) {
// LocalStrategy의 validate가 성공하면 req.user에 사용자 정보가 담깁니다.
return this.authService.login(req.user); // JWT 토큰 생성 및 반환 로직
}
}
728x90
3.2. JWT Guard (모든 인증 필요 요청)
인증이 필요한 모든 API 엔드포인트에 AuthGuard('jwt')를 적용하여 JWT의 유효성을 검증합니다.
// users.controller.ts
import { Get, UseGuards, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('users')
export class UsersController {
// 💡 JwtStrategy를 실행하도록 지시하는 Guard
@UseGuards(AuthGuard('jwt'))
@Get('profile')
getProfile(@Request() req) {
// JWT가 유효하면 req.user에는 JwtStrategy에서 반환한 Payload 정보가 담겨 있습니다.
return req.user;
}
}
4. 🥇 NestJS 인증 시스템의 장점
- 명확한 책임 분리:
- Strategy: 사용자 검증 및 토큰 처리 로직만 담당.
- Guard: 해당 라우트 접근 권한을 허용/거부하는 역할만 담당.
- Controller: 인증/인가에 신경 쓰지 않고 비즈니스 로직만 수행.
- 플러그인 방식: Passport 덕분에 JWT 외에도 Google, Facebook 등 다른 OAuth 인증 방식을 쉽게 추가할 수 있습니다.
728x90
'Nest.js를 배워보자 > 7. NestJS 인증 시스템 구축 — JWT & Passport 실전' 카테고리의 다른 글
| Role 기반 권한 관리 (Role-Based Access Control, RBAC) (0) | 2025.12.02 |
|---|---|
| WT 인증 시스템 구축: Refresh Token 패턴 (0) | 2025.12.02 |
| Passport Strategy 구현: Local & JWT 실전 (0) | 2025.12.02 |