Auth Guard를 활용하여 요청 시 유저 인증 정보를 검증하고, 인증된 유저 정보를 가져오는 기능을 구현한다.
pnpm add @nestjs/passport passport passport-local @nestjs/jwt passport-jwt @nestjs/swagger
pnpm add -D @types/passport-local @types/passport-jwt
인증 처리를 위해 Passport를 사용하고, 토큰 기반 인증을 위해 JWT를 함께 사용한다.
또한 API 문서 자동화를 위해 Swagger를 설치한다.
요청 → Guard → Strategy → validate → controller
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class AccessTokenGuard extends AuthGuard('jwt-access-token') {}
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
type JwtPayload = {
sub: string;
email?: string;
name?: string;
picture?: null;
iat?: number;
};
@Injectable()
export class AccessTokenStrategy extends PassportStrategy(
Strategy,
'jwt-access-token',
) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.AUTH_SECRET!,
});
}
async validate(payload: JwtPayload) {
return payload;
}
}
Guard를 통해 Strategy로 진입하면, 먼저 constructor(생성자)가 실행된다.
이 과정에서 JWT를 어떤 방식으로 추출할지, 어떤 비밀 키로 검증할지 등의 인증 설정을 정의한다.
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.AUTH_SECRET!,
});
이후에 토큰이 유효한 경우 validate 함수가 실행된다. validate는 검증된 결과를 처리하는 단계라고 볼 수 있다. 최종적으로 인증된 사용자 정보가 req.user에 주입된다.
@Get('user-test')
@UseGuards(AccessTokenGuard)
@ApiBearerAuth('access-token')
testUser(@Req() req: Request & { user: JwtPayload }) {
console.log(req.user);
return 'test complete';
}
Swagger는 API를 문서화하고 테스트할 수 있게 해주는 도구 NestJS에서는 @nestjs/swagger를 통해 쉽게 적용할 수 있음
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('API Docs')
.setDescription('NestJS JWT 인증 API 문서')
.setVersion('1.0')
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'Authorization',
in: 'header',
},
'access-token',
)
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
.addBearerAuth(..., 'access-token') 이 부분이 Controller에서 사용햇던 @ApiBearerAuth('access-token') 이 부분과 이름이 맞아야함.
const config = new DocumentBuilder()
Swagger 문서의 기본 설정을 정의하는 빌더 객체
API 문서의 제목, 설명, 인증 방식 등을 설정
