如何在我的 SPA 加载期间验证和更新 JWT id_token?

How to verify and renew a JWT id_token during my SPA load?

我是 OAuth 2.0OpenID Connect 的新手,我无法理解流程的某些部分(或者我应该使用哪些最佳实践)...

抱歉冗长 post :)

我的设置:

  1. OP(OpenID 提供商)基本上是一个 express 服务器,它使用 oauth2orize-openidpassport 来验证和授权用户。我们称它为http://authserver.com

  2. A Single page application (react+webpack) 需要根据我的 OP 对用户进行身份验证,我们称它为 http://my-spa.com

因为它是一个 SPA(由 webpack 静态提供)我必须使用 Implicit Flow.

我的问题

一旦用户导航到 http://my-spa.com,应用程序就会加载,然后它会检查 localStorage 是否存在 id_token

localStorage 中没有 id_token 加载:

  1. 因为没有令牌,我重定向到 http://authserver.com/dialog/authorize
    • response_type=id_token
    • scope=openid profile
  2. 一旦用户成功通过身份验证和授权,authserver 重定向回 my-spa,URI 片段 id_token
  3. 我将 id_token 存储在 localStorage 中,用户可以开始使用该应用程序。

加载 localStorage 中有一个 id_token

用户关闭浏览器并再次打开。 这是我无法理解该做什么的地方。由于已经有一个令牌(来自以前的登录),我需要检查它是否有效。

这样做的最佳做法是什么?以下是我认为正确的内容:

  1. 重定向到 http://authserver.com/dialog/authorize 使用:
    • prompt=none
    • id_token_hint=CURRENT_TOKEN
  2. 一旦 OP 收到此请求,它应该验证 JWT 签名,尝试自动批准用户并使用新的 JWT 重定向回来。

令牌获取在一段时间后过期

假设一个登录用户的 JWT 已过期,它应该什么时候请求一个新的?什么应该触发续订?

/tokeninfo/userinfo 有什么用?

据我了解,JWT 存储了识别用户所需的所有数据。但是我见过调用 /tokeninfo/userinfo.

的示例

如果我已经有了 sub ID,这些端点是否仅用于验证令牌(假设我只需要主题的 ID)?

JWT 签名验证

除了 OP 之外,my-spa 是否应该验证 JWT 签名(也许使用 public 密钥)?

重新使用此令牌访问第三个服务的 REST API

如果我有另一个 Web 服务 api,将其命名为 http://my-service.com/api,它需要知道哪个用户从我的 SPA 调用它,这些是我认为我需要执行的步骤:

  1. id_token 作为 Bearer 令牌添加到每个 ajax 请求
  2. my-service.com 应该验证 JWT 签名(使用 public 密钥?)并决定是允许还是拒绝访问受保护的资源

如有任何帮助,我们将不胜感激!

你的问题很大,我会尽量笼统地回答所有标有?的短语(不考虑你使用的具体框架)

there's an id_token in localStorage on load.

The user closed the browser and opened it again. What are the best practices to do so?

您可以选择乐观并继续使用令牌,或悲观并申请一个新令牌。

  • 如果过期时间足够长,则继续使用令牌。我假设令牌在每个请求中都经过验证,因此如果令牌无效,您将收到 401,您可以请求一个新的

  • 请求新令牌 如果有效期很短或者您希望在浏览器打开您的应用程序时要求新的用户身份验证。如果您想检查 JWT 是否仍然有效,使用身份验证服务器的重定向对于 SPA 来说不是 user-friendly。我建议执行 AJAX 调用以验证并请求新令牌。

token get's expired after some time

这是我上面解释的第一个案例。您可以阻止它在每次请求时或在固定时间段(即 1 小时

之后)发出新令牌

what are the /tokeninfo or /userinfo for?

我不知道这些服务,但可以推断出它们的含义。 JWT 已签名,因此您可以信任其中包含的数据(签名仍然有效)

JWT signature verification, Beside the OP, should my-spa verify the JWT signature (with a public key perhaps)?

您必须验证每个请求的签名。如果您使用对称密钥(即 HMAC),JWT 将使用相同的密钥进行签名和验证。使用非对称密钥 (RSA),JWT 使用私钥签名并使用 public 密钥

进行验证

re-using this token to access a REST API of a third service

Add the id_token as a Bearer token to each ajax request,

正确,通常使用授权 header

my-service.com should validate the JWT signature (with a public key?) and decide whether to allow or deny access to the protected resource

当然,任何使用 JWT 的服务都必须验证签名。外部服务不拥有私钥,因此在这种情况下需要使用非对称密钥。您需要发布 public 密钥,以便外部服务可以验证令牌