[nest.js] jwt token 과 cookie 를 이용한 login 구현
jwt 를 이용하여 인증하는 api application은 local test가 불편하다.
인증시 token이 bearer token 형태일 경우
postman 에서 매번 login 후 token 값 알아내기 -> api 마다 수동으로 token 값 넣기 식으로 진행된다.
cookie 에 token 을 넣고 알아서 인증단계를 거치면 이런 노가다가 필요없다.
사전준비
패키지를 설치해 준다.
npm i --save cookie-parser
npm i --save-dev @types/cookie-parser
npm i --save @nestjs/jwt @nestjs/passport passport passport-jwt
main.ts 에 cookie parser 를 사용하도록 설정한다.
app.use( cookieParser() );
tsconfig.json 아래 내용을 추가해 준다.
"esModuleInterop": true
jwt strategy 작성
cookieExtractor 라는 함수만 보면 된다. 내용은 request 의 cookie 에 저장된 token 에 접근하는 것이다.
import { Injectable, NotFoundException, UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { ExtractJwt, Strategy } from "passport-jwt";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { User } from "../user/user.entity";
let cookieExtractor = function( req )
{
var token = null;
if ( req && req.cookies )
{
token = req.cookies["Authentication"] || req.header;
}
return token;
};
@Injectable()
export class JwtStrategy extends PassportStrategy( Strategy )
{
constructor( @InjectRepository( User ) private userRepository : Repository<User> )
{
super( {
secretOrKey : process.env.JWT_SECRET || jwtConfig.get( "secret" ),
jwtFromRequest : cookieExtractor
} );
}
async validate( payload ) : Promise<UserDTO>
{
const { id } = payload;
// const uid : string = payload["uid"];
const user : UserDTO = await this.userService.findOne( { id : id } );
if( !user )
throw new UnauthorizedException( 'not user' );
return user;
}
}
auth.module.ts 에 import 추가
PassportModule.register( { defaultStrategy : "jwt" } ),
JwtModule.register
(
{
secret : process.env.JWT_SECRET_KEY
signOptions : { expiresIn : process.env.EXPIRES_IN }
}
),
login 시 cookie 에 token 저장
controller 의 response 객체에 jwt service로 발급받은 token 을 저장한다
사용예시
@UseGuards decorator 로 주입된 controller 함수를 사용할 경우 자동으로 인증처리가 된다.
@Get( '/myinfo' )
@UseGuards( AuthGuard() )
getUser( @GetUser() user : User ) : User
{
return user;
}