HooneyLog

Custom decorator를 사용하여 header에 있는 jwt 받아오기

프로필 이미지

Seunghoon Shin

2022년 5월 28일 10:22

이번 글에서는 Nest.js에서 User라는 커스템 데코레이터를 사용하여 request header에 있는 jwt 를 받아오는 방법을 알아보겠습니다

실행 절차는 아래와 같이 됩니다.

  • 서버로 부터 요청이 들어왔을때 그 요청을 Interceptor하여 request에 들어있는 요청정보를 가로채기
  • 그 요청 정보에 있는 headers에 접근후 autorization값으로 부터 jwt 받아오기
  • jwt를 decode하여 User Custom Decorator에서 사용할 수 있도록 만들어주기
  • 코드 살펴보기

    //main.ts
    @Module({
      imports: [UserModule, PrismaModule, HomeModule],
      controllers: [AppController],
      providers: [
        AppService,
        { provide: APP_INTERCEPTOR, useClass: UserInterceptor },
      ],
    })
    export class AppModule {}

  • main.ts로부터 provider에 APP_INTERCEPTOR 를 넣어 interceptor를 위한 설정을 진행해줍니다.
  • useClass를 사용하여 어떤 클래스를 사용하여 interceptor를 진행할지 설정해줍니다. ( 아직 UserInterceptor를 안만든 상태이며, 아래 코드처럼 intercept 폴더를 만들어 그 안에서 관련 로직을 처리할 것입니다. )
  • //src/user/interceptors/user.interceptor.ts
    import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
    import { Observable } from 'rxjs';
    import * as jwt from 'jsonwebtoken';
    
    export class UserInterceptor implements NestInterceptor {
      intercept(
        context: ExecutionContext,
        next: CallHandler<any>,
      ): Observable<any> | Promise<Observable<any>> {
        const request = context.switchToHttp().getRequest();
        const token = request?.headers?.autorization.split('Bearer ')[1];
        const user = jwt.decode(token);
        request.user = user;
        return next.handle();
      }
    }
  • NestInterceptor 를 implements 받아 Interceptor를 위한 class를 만들어줍니다.
  • context.switchToHttp().getRequest()를 사용하여 request 정보들을 가져옵니다.
  • request 정보로부터 headers에 있는 autorization에서 jwt를 가져옵니다
  • jwt를 decode해줍니다
  • decode된 user 정보를 request key value로 설정해줍니다
  • //src/decorators/user.decorator.ts
    import { createParamDecorator, ExecutionContext } from '@nestjs/common';
    
    export interface UserInfo {
      name: string;
      id: number;
      iat: number;
      exp: number;
    }
    
    export const User = createParamDecorator((context: ExecutionContext) => {
      const request = context.switchToHttp().getRequest();
      return request.user as UserInfo;
    });
  • UserInterceptor 에서 만들어준 user 정보를 return합니다 ( request에 user 정보를 넣어줬기때문입니다. )
  • @Post()
      createHome(@Body() body: CreateHomeDto, @User() user: UserInfo) {
        return this.homeService.createHome(body, user.id);
      }
  • 위 코드 처럼 User Decorator를 사용합니다
  • user객체로부터 원하는 데이터를 유연하게 사용합니다.