GraphQL의 토큰 만료 응답 관리

2021. 5. 14. 20:03Web

728x90

GraphQL을 사용한지는 몇년이 지났지만, 토큰 인증을 사용할 때 토큰의 만료응답을 주기 위해서는 항상

NetworkError를 고집했었습니다. 즉 HTTP STATUS에서 401을 응답하기 위함이었습니다.

 

하지만 Apollo의 공식 문서를 보면 UNAUTHENTICATED 가 이미 Error Codes로 정의되어 있는 것을 볼 수 있습니다.

https://www.apollographql.com/docs/apollo-server/data/errors/#error-codes

 

Error handling

Making errors actionable on the client and server

www.apollographql.com

 

GraphQL에서는 굳이 삽질하지 말고 GraphQLError로 반환하라는 그런 상황인데,

대체로 NetworkError응답을 지원하지 않는 일부 언어 또는 프레임워크 써드파티등이 있기도 하며,

GraphQLError로 반환할 경우 extensions를 통해 커스텀해서 에러를 반환할 수 있습니다.

 

https://www.apollographql.com/docs/apollo-server/data/errors/#including-custom-error-details

 

Error handling

Making errors actionable on the client and server

www.apollographql.com

 

위 링크에서는 커스텀 오류 정보를 extensions로 표기하는 방법을 작성하고 있으며,

Python 예시로 작성할 경우 다음과 같이 작성할 수 있습니다.

 

from graphql import GraphQLError


class Example:
	
    @staticmethod
    def example_method():
    	return GraphQLError('AuthenticationError', extensions={
          'code': 401,
          'name': 'UNAUTHENTICATED',
          'message': 'Authentication Error',
        })

 

 

이렇게 될 경우 Vue Apollo를 예시로 error handling에서는 다음과 같이 접근하여 받아먹을 수 있습니다.

import { onError } from '@apollo/client/link/error'

const errorLink = onError(
  ({ graphQLErrors, networkError, operation, forward }: any) => {
    if (graphQLErrors && graphQLErrors[0].extensions) {
      const status = graphQLErrors[0].extensions.code
      if (status === 401) {
        // this your code!
      }
    } else if (graphQLErrors) {
      console.error(graphQLErrors[0].message)
    }

    if (networkError) {
      console.error(networkError)
    }
  }
)

export default errorLink

networkError 보다 더 깔쌈한 듯..

728x90