Nestjs graphql Authentication으로 Login 구현

Changwoo Yoo·2022년 5월 17일
1

코딩

목록 보기
4/4
post-custom-banner

들어가며...

Nestjs docs가 좋긴 한데 authentication 부분은 REST API 기준으로 설명이 되어 있고 graphql은 상대적으로 덜 설명되어 있어서 뭐가 뭔지 몰랐다. 그래도! 이제는 할 수 있다! ㅎㅎㅎㅎ

REST API와의 차이점

  1. login을 수행할 때 login input은 REST API에서는 request body에 담겨 있었다. 하지만 graphql에서는 @Arg()로 이 input을 받기 때문에 이 input 값이 Context에 저장되어 있다.
  2. 또한 JWT Token으로 Authenticaton을 할 때 REST API에서는 request에 token이 들어있으나 graphql에서는 context에 request file이 들어 있다.

따라서 login input과 request를 Context로부터 꺼내주는 작업이 필요하다.
GqlAuthGuard와 JwtAuthGuard에 다음과 같은 코드들을 추가해줘서 이를 수행해주면 된다.

gql-auth.guard.ts

import { ExecutionContext, Injectable } from '@nestjs/common'
import { GqlExecutionContext } from '@nestjs/graphql'
import { AuthGuard } from '@nestjs/passport'

@Injectable()
export class GqlAuthGuard extends AuthGuard('local') {
  // graphql context로부터 logininput 가져오기
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context)
    const request = ctx.getContext()
    request.body = ctx.getArgs().loginInput
    return request
  }
}

jwt-auth.guard.ts

import { ExecutionContext, Injectable } from '@nestjs/common'
import { GqlExecutionContext } from '@nestjs/graphql'
import { AuthGuard } from '@nestjs/passport'

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  // graphql context에 있는 request를 넘겨줌
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context)
    return ctx.getContext().req
  }
}

리졸버 부분은 이렇게 구현해주면 된다.

@Resolver()
export class AuthResolver {
  constructor(private authService: AuthService) {}

  @Mutation(() => LoginResponse)
  @UseGuards(GqlAuthGuard)
  async login(@Args('loginInput') loginInput: LoginInput, @Context() context) {
    // UseGuard를 통해 authentication이 완료되면 user가 context에 저장되어 있음.
    return this.authService.login(context.user)
  }
}

이런 식으로 코드를 추가해주면 request header json 파일에
"Authorization": "Bearer alsdnflabgqobozbgaboisldkblsba" 식으로 넣어주면
graphql에서 정확하게 이 JWT Token을 인식하는 것을 알 수 있다.

나머지 부분은 REST API와 똑같이 구현해주면 된다.

profile
끊임없이 성장하고 발전하고 싶은 Changwoo입니다 :)
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 6월 22일

도움 많이 됐습니다 감사합니다

답글 달기