【问题标题】:Using refresh token in graphQL client-side when token has expired令牌过期时在graphQL客户端中使用刷新令牌
【发布时间】:2020-06-22 06:45:44
【问题描述】:

场景是:

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

这是我目前的代码:

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

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

我们如何改进此流程,以便在用户发出请求时刷新令牌而不会出现错误?如果它导致错误,那么像请求之类的东西会被“搁置”,然后一旦刷新令牌,就会处理它。但我不知道该怎么做。

或者有什么其他方法可以改进这个流程?

【问题讨论】:

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


【解决方案1】:

您可以通过终止链接创建一个可以在执行操作之前运行的链接。您可以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: {
      ...
    }
  }
})

【讨论】:

  • 我已经包含了一个示例。 @Andres,你有什么不清楚的地方?
猜你喜欢
  • 2020-08-25
  • 2022-11-29
  • 2019-04-07
  • 2018-12-08
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
相关资源
最近更新 更多