[nest.js] jwt를 이용해서 request 에 사용자 정보 넣기

회원기반 사이트는 반드시 인증이 필요하다.

웹개발에서 jwt라는 쉬운 방법이 있는데 nest.js에서도 지원이 된다.

local에서는 jwt로 발급된 token을 bearer token 이나 cookie를 이용하여 테스트 할 수 있다.

cookie를 이용한 방법을 소개한다.

a. strategy
인증을 담당하는 module에 import할 strategy 클래스 작성
validate에서 return되는 객체는 request 에 담겨진다.

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 : "secret1234",
				jwtFromRequest : cookieExtractor
			} );
	};

	async validate( payload ) : Promise<User>
	{
		const { id } = payload;
		const user : User = await this.userRepository.findOneBy( { id : id } );
		if ( !user )
			throw new UnauthorizedException( "음는 사람인디요" );

		return user;
	}
}

b. decorator 작성
GetUser라는 decorator를 작성한다. 이렇게 하면 request 를 통하지 않고도 controller 에서 @GetUser 로 주입된 parameter를 통해 쉽게 user 객체에 접근이 가능해진다.

import { createParamDecorator, ExecutionContext } from "@nestjs/common";
import { User } from "../user/user.entity";

export const GetUser = createParamDecorator( ( data, ctx : ExecutionContext ) : User =>
{
	const req = ctx.switchToHttp().getRequest();
	return req.user;
} )

c. module
사용하려는 module 에 strategy 클래스에서 설정한 동일한 secret 값으로 등록한다.

import { Module } from "@nestjs/common";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { UserHttpModule } from "../user/user-http.module";
import { JwtModule } from "@nestjs/jwt";
import { PassportModule } from "@nestjs/passport";
import { JwtStrategy } from "./jwt.strategy";
import { TypeOrmModule } from "@nestjs/typeorm";
import { User } from "../user/user.entity";

@Module( {
	imports : [
		TypeOrmModule.forFeature([User]),
        PassportModule.register({ defaultStrategy : 'jwt'} ),
		JwtModule.register(
			{
				secret : 'secret1234',
				signOptions : { expiresIn : 3600 }
            }
		),
		UserHttpModule],
	controllers : [AuthController],
	providers : [AuthService, JwtStrategy],
	exports : [JwtStrategy, PassportModule]
} )
export class AuthModule {}

d. controller 사용 예시
@GetUser 로 주입된 parameter 를 통해 user 객체에 접근이 가능하다.

@Post()
	async save( @GetUser() user : User, @Body() board : Board ): Promise<Board>
	{
		return await this.boardService.insert( board, user );
	}

Subscribe to X세대 신입사원

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe
774-86-01972 cinnabar.3d@gmail.com