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

cat*_*use 2 error-handling access-token jwt graphql refresh-token

场景是:

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

这是目前我的代码:

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

const link = ApolloLink.from([errorLink, terminatingLink]);
Run Code Online (Sandbox Code Playgroud)

我们如何改进此流程,以便在用户发出请求时刷新令牌而不会出错?如果请求导致错误,则类似请求将被“搁置”,然后一旦刷新令牌,就会对其进行处理。但我不知道如何做到这一点。

或者我们有没有其他方法可以改进这个流程?

Dan*_*den 5

您可以创建一个可以在通过终止链接执行操作之前运行的链接。您可以创建自己的无状态链接,但您也可以使用setContext摆脱困境,它可用于在我们处理时设置您的请求标头。

由于您使用的是 JWT,您可以在客户端对其进行解码以提取到期值,并使用它来确定是否需要将请求发送到服务器之前刷新令牌。如果您没有使用 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: {
      ...
    }
  }
})
Run Code Online (Sandbox Code Playgroud)