如何处理 React Spa 上的刷新令牌?

Posted

技术标签:

【中文标题】如何处理 React Spa 上的刷新令牌?【英文标题】:How to handle refresh token on react spa? 【发布时间】:2020-09-11 09:30:46 【问题描述】:

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

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

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

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

【问题讨论】:

你能提供代码吗? 我在问这种方法是否正确?我对代码没有任何问题。 根据本文档hasura.io/docs/1.0/graphql/manual/subscriptions/index.html,websocket 客户端使用浏览器 cookie,因此它们似乎必须处理访问令牌过期,我在我的手动 graphql 服务器中使用 apollo 并发送新令牌作为webscoket 出错,因为当时没有其他方法,但 Hasura 我不知道如何处理,如果不给他们发票,他们必须处理。 【参考方案1】:

让我们使用扣除。显然,您可以在客户端检查过期时间,也可以让 Hasura 为您完成(并在令牌过期时返回错误)。

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


OT 但恕我直言,JWT 在到期、黑名单等方面并不是一个很好的解决方案。例如:

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

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

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


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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于如何处理 React Spa 上的刷新令牌?的主要内容,如果未能解决你的问题,请参考以下文章

Google API V 3.0 .Net 库和 Google OAuth2 如何处理刷新令牌

SPA 中的令牌存储和刷新选项

SPA 使用的经过身份验证的 Rest API:如何获取用于登录和注册表单的 CSRF 令牌?

SPA 的 Cookie 与基于令牌的身份验证?

SPA中令牌存储和刷新的选项

FBSDK令牌过期情况如何处理?