令牌过期时在graphQL客户端中使用刷新令牌

时间:2020-03-10 11:12:32

标签: error-handling graphql jwt access-token refresh-token

情况是:

  1. Web应用已打开,但令牌已过期。
  2. 然后用户执行一些操作以发出api请求。
  3. GraphQL返回Error: GraphQL error: unauthorized
  4. 由于错误,应用程序无响应。糟糕的用户体验。
  5. 来自onError方法的
  6. apollo-link-error捕获了错误,因此可以调用refreshToken()(需要到期的jwt)。
  7. 生成新令牌并存储以供使用。
  8. 下一个用户操作将正常进行。

这是我目前的代码:

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    refreshToken();
  }
});

const link = ApolloLink.from([errorLink, terminatingLink]);

我们如何改善此流程,以便在用户发出请求时不会出错而刷新令牌?如果请求导致错误,则将请求“暂停”,然后刷新令牌后,将对其进行处理。但是我不确定该怎么做。

或者我们还有其他方法可以改善这一流程吗?

1 个答案:

答案 0 :(得分:3)

您可以创建一个链接,该链接可以通过终止链接在执行操作之前运行。您可以create your own stateless link,但也可以使用setContext,它可以在我们使用时设置请求标头。

由于您使用的是JWT,因此可以decode it on the client side提取到期值,并使用该值来确定是否需要刷新令牌 ,然后再将请求发送到服务器。如果您没有使用JWT,但是服务器返回了带有令牌的到期时间,则将应用相同的策略。

const contextLink = setContext(async () => {
  const { exp } = jwtDecode(jwt)
  // subtracts a minute to account for latency
  const expirationTime = (exp * 1000) - 60000
  if (Date.now() >= expirationTime) {
    await refreshToken()
  }
  return {
    // you can set your headers directly here based on the new token
    headers: {
      ...
    }
  }
})