如何处理 react spa 上的刷新令牌?

How to handle refresh token on react spa?

我有两台服务器。一个用于查询数据库并提供应用程序数据的 Hasura GraphQL api。另一个是用于身份验证的节点服务器。这两个服务器不在同一个域中。

我有一个 React spa 客户端。当用户登录时,节点服务器使用 hasura graphql 端点验证凭据,并向客户端提供 jwt 令牌和刷新令牌。刷新令牌通过 httpOnly cookie 发送,因为反应客户端和节点服务器位于同一域中。

现在,当 jwt 令牌过期时,我想使用作为 cookie 自动发送到节点服务器的刷新令牌静默刷新 jwt 令牌。我将如何实施?

我能想到的一种方法是,在客户端解码 jwt,如果它已过期,我会向节点服务器上的刷新令牌端点发送请求,并在向其发送任何请求之前获取新的 jwt 令牌需要作为授权发送的访问令牌的 hasura graphql 服务器 header。这意味着我必须在每个 graphql 请求之前进行此检查。鉴于我的应用程序架构,这是优化方式还是有任何其他方式静默刷新令牌?

让我们使用演绎法。显然,您可以在客户端检查过期时间,也可以让 Hasura 为您做这件事(并且 return 每当令牌过期时都会出现错误)。

如果您在客户端检查它,您将在每次调用 Hasura 之前损失几毫秒,但只要您检测到过期令牌,就会节省一次 Hasura 往返。我会随时通过 HTTP 调用对 JWT 有效负载进行 base64 解码,所以 IMO 没有更好的方法来处理 JWT 自动刷新,如果这是你唯一关心的。


OT 但恕我直言,JWT 在涉及过期、黑名单等问题时并不是一个很好的解决方案。例如:

  • 如果在某个时候您决定需要检查帐户是否被暂停怎么办?然后,您必须在每次调用 Hasura 之前开始调用您的身份验证服务器;
  • 即使您处理了这个问题,如果您决定(出于任何原因)在应用程序加载时执行自动登录怎么办?还是每隔一段时间自动刷新?使用单个选项卡很容易做到这一点,但是一旦您的用户同时打开应用程序的两个或更多选项卡,事情就会变得非常快。

我怀疑在许多此类情况下,人们最终会实施 会话,只是没有 cookie,这有点像重新发明轮子。

我可以建议您改用 Hasura 的 webhook 身份验证系统,如果您发现自己在不久的将来会走上类似的道路 - 它可能只是最佳选择。


顺便说一句,此类问题可能更适合软件工程 SE。

这篇博客非常简洁地解释了 JWT 及其相关用例,https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/ 它涵盖了静默刷新的用例以及如何设计身份验证服务器。