Guard
Guard는 요청(request)을 처리하기 전에 실행되며, 주로 권한 부여(Authorization) 로직을 수행한다. Guard는 request이 특정 조건을 만족하는지 여부를 확인하고, 그렇지 않으면 request를 차단한다.
- 역할: 요청이 보호된 리소스에 접근할 자격이 있는지 확인한다.
- 동작 방식: 'canActivate' method를 구현하여, true를 반환하면 요청이 진행되고, false를 반환하면 요청이 차단된다.
Strategy
Strategy는 인증(Authentication) 로직을 처리한다. 다양한 인증 전략(e.g. JWT, OAuth, Local 등)을 구현할 수 있으며, Passport.js를 통해 이를 쉽게 통합할 수 있다.
- 역할: 사용자의 자격 증명(e.g. JWT 토큰)을 확인하고 인증한다.
- 동작 방식: 인증이 성공하면 사용자 정보를 반환하고, 실패하면 예외를 던진다.
Passport
Node.js용 인증 미들웨어이다. 다양한 인증 전략을 지원하며. NestJS에서 쉽게 사용할 수 있도록 Passport 모듈을 제공한다.
- 역할: 다양한 인증 전략을 통합하여 사용할 수 있게 한다.
- 동작 방식: 특정 전략을 사용하여 사용자를 인증하고, 인증 결과를 바탕으로 Guard가 요청을 처리할 수 있도록 한다.
JWT
JWT는 JSON 기반의 인증 토큰이다. 주로 client와 server 간에 인증 정보를 안전하게 전송하기 위해 사용된다.
- 역할: 사용자 인정 정보를 포함하는 토큰을 생성하고 검증한다.
- 동작 방식: 서버는 사용자가 로그인할 때 JWT를 생성하여 클라이언트에 전달하고, 클라이언트는 이후 요청 시 이 토큰을 포함하여 서버에 전달한다. 서버는 토큰을 검증하여 사용자를 인증한다.
동작 원리
사용자 로그인
- 사용자가 로그인 정보를 서버에 제출
- 서버는 사용자를 인증하고, JWT 토큰을 생성하여 클라이언트에 반환
JWT 토큰을 포함한 요청
- 클라이언트는 보호된 리소스에 접근하기 위해 JWT 토큰을 포함한 요청을 서버에 보낸다.
Guard가 요청을 가로채고 검사
- 요청이 서버에 도달하면, Guard가 이를 가로채고 'canActivate' method를 호출
- 'canActivate' 메서드는 Passport를 사용하여 JWT 전략을 통해 토큰을 검증
Strategy가 토큰 검증
- JWT 전략이 토큰을 검증한다. 토큰이 유효하면 사용자 정보를 반환하고, 그렇지 않으면 예외를 던진다.
Guard가 요청 허용 여부 결정
- JWT 전략이 반환한 사용자 정보를 바탕으로 Guard가 요청을 허용할지 결정
- 인증이 성공하면 요청이 처리되고, 실패하면 요청이 차단
// JWT Strategy
import { Strategy, ExtractJwt } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET, // 환경 변수에서 비밀 키를 가져옴
ignoreExpiration: false, // 토큰 만료 시간을 무시하지 않음
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
// Auth Guard
import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext) {
return super.canActivate(context);
}
}
// Auth Module
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt/jwt.strategy';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt', session: false }),
JwtModule.register({
secret: process.env.JWT_SECRET,
signOptions: { expiresIn: '1y' },
}),
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
})
export class AuthModule {}
// Controller
import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
@Controller('cats')
export class CatsController {
@UseGuards(JwtAuthGuard)
@Get()
findAll() {
return [];
}
}
요약
- Guard: 요청이: 보호된 리소스에 접근할 자격이 있는지 확인
- Strategy: 사용자의 자격 증명을 확인하고 인증한다.
- Passport: 다양한 인증 전략을 통합하여 사용할 수 있게 한다.
- JWT: 사용자 인증 정보를 포함하는 토큰을 생성하고 검증