끄적이는 개발노트
NestJS - JWT 토큰 기반 인증 구현 (1) 본문
728x90
이번 포스트에서는 로그인 구현에서 가장 많이 사용되는 JWT 토큰에 대해 정리한다.
토큰 기반의 인증 시스템은 로그인 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 담아 유저 인증을 처리하는 방식이다.
auth 모듈과 user 모듈은 각각 본인의 프로젝트에 맞게 구성되어 있다는 전제 하에 필요한 코드들만 빼내서 정리한다.
1. 설치
yarn add @nestjs/passport passport passport-local @nestjs/jwt passport-jwt
yarn add -D @types/passport-local @types/passport-jwt
2. Jwt strategy
auth 디렉토리 레벨에서 strategy 폴더를 만든 후, 아래의 파일을 추가한다.
// auth/strategy/jwt.strategy.ts
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';
import { UserService } from 'src/user/user.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private userService: UserService;
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
async validate(payload: any) {
const user = await this.userService.findOne(payload._id);
if(!user) throw new Unauthorizedexception();
return user;
}
}
passport 전략을 확장하여 JwtStrategy를 선언해주는데 이 때 super 메소드를 통해 몇가지 값을 초기화해준다.
- jwtFromRequest : Jwt가 추출되는 방법으로, 헤더로부터 토큰을 추출하는 표준 접근 함수를 사용
- ignoreExpiration : false를 주면 해당 토큰의 만료여부를 검증하여 만료 시, 자동으로 401 Unauthorized 에러를 뱉는다.
- sercretOrKey : 본인이 설정한 jwt secret key(노출되면 안되는 값으로 env 혹은 암호화된 값 등을 활용
validate 함수에서는 넘어온 토큰 값을 통해 user db를 조회하여 실제 존재하는 값인지를 찾는 로직을 추가하면 된다. 그 외 본인 프로젝트에서 검증해야 될 토큰 혹은 user 조건이 있다면 여기에 추가하면 된다.
값을 조회하여 있으면 그대로 db에서 찾은 user 값을 반환하고, 없으면 Unauthorized 에러를 뱉는다.
3. Jwt guard
auth 디렉토리 레벨에 guard 폴더를 만든 후, 아래의 파일을 추가한다.
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
본인은 더 확장할 필요가 없어 기존 제공된 AuthGuard 클래스만을 사용했지만, 필요에 따라 아래와 같이 확장하여 사용이 가능하다고 한다.
import {
ExecutionContext,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext) {
// Add your custom authentication logic here
// for example, call super.logIn(request) to establish a session.
return super.canActivate(context);
}
handleRequest(err, user, info) {
// You can throw an exception based on either "info" or "err" arguments
if (err || !user) {
throw err || new UnauthorizedException();
}
return user;
}
}
지금까지 strategy와 guard에 대해 정리해보았다.
다음 포스트에서 이어서 auth module, service, controller를 수정하는 방법을 정리해본다.
728x90
'JavaScript > NestJS' 카테고리의 다른 글
NestJS - 알림톡 전송 (SOLAPI) (0) | 2023.06.22 |
---|---|
NestJS - JWT 토큰 기반 인증 구현 (2) (0) | 2023.06.19 |
NestJS - Middleware (0) | 2021.11.03 |
NestJS와 MongoDB 연결하기(3) - CRUD (0) | 2021.10.08 |
NestJS와 MongoDB 연결하기(2) - Module, Service, Controller (0) | 2021.10.08 |