【问题标题】:Where to store refresh_token for SPA/REST app with third-party OAuth2 service?在哪里存储带有第三方 OAuth2 服务的 SPA/REST 应用程序的 refresh_token?
【发布时间】:2015-03-14 01:02:40
【问题描述】:

我有一个客户端 (SPA)/服务器 (REST) 应用程序,我需要对客户端进行身份验证并让它们在资源服务器中保持登录状态。 应用程序通常必须使用位于第三方授权服务器上的外部 OAuth2 服务。 现在的问题是:refresh_token 应该存储在哪里?我有两个想法。

我故意省略了 refresh_token 过期的情况。

假设

  • 始终返回有效令牌以响应对任何安全资源的请求和登录请求。
  • 与授权服务器的所有通信都必须通过资源服务器,因为需要 client_id 和 client_secret。

第一个场景

  1. 服务器存储由令牌映射的refresh_token,并将令牌发送给客户端以响应登录请求。
  2. 客户端使用令牌发出请求。
  3. 服务器检查令牌是否有效。如果不是,它使用与令牌关联的 refresh_token 来生成一个新令牌。现在一分钟(或任何配置的持续时间)旧令牌被映射到新令牌,新令牌被映射到 refresh_token 以使用旧令牌处理排队请求。
  4. 客户端使用令牌发出请求。
  5. 服务器检查令牌是否有效。如果不是,则检查令牌是否映射到新令牌。如果是这样,它的行为就像使用新令牌发送请求一样(参见步骤 3)。否则发送 401。

第二种情况

  1. 服务器将令牌和 refresh_token 发送到客户端,以响应登录请求。
  2. 客户端使用令牌发出请求。
  3. 服务器检查令牌是否有效。如果不是,它会以 401 响应。
  4. 如果客户端使用 401 状态的响应,它会尝试刷新令牌并使用新令牌发出相同的请求。

我知道这两种解决方案都有其弱点。有没有适用于这个问题的好的做法?

【问题讨论】:

    标签: javascript security rest oauth


    【解决方案1】:

    access-token 和 refresh-token 应该保留在它们被提取的位置,尤其是当您的后端没有使用 HTTPS 时。

    没有自己的 REST 后端的 SPA 应该使用 OAuth 隐式流来获取访问令牌。隐式流不支持刷新令牌。

    具有服务器端后端的应用程序应使用授权代码流(您的情况)。授权代码由后端交换以访问和刷新令牌,并且应该保留在那里。您的 REST 后端可以使用 access-token 访问第三方资源,并在必要时使用 refresh-token 更新 access-token。

    【讨论】:

      【解决方案2】:

      在我看来,第二种情况是最可行的。首先,您的授权服务器不必与您的资源服务器相同。您只使用刷新令牌从授权服务器获取新的访问令牌。但是授权服务器和资源服务器可以在同一个服务器上实现。

      第一个场景中的客户端如何取回新的访问令牌?它正在请求资源(第 3 步)并且不希望取回新令牌。

      我会将刷新令牌存储在客户端的浏览器本地存储或其他东西中。这不是很安全,但可能是您能做的最好的。

      【讨论】:

      • 感谢您的回答。正如问题中所指出的那样 - 授权服务器是第三方,因此它不与资源服务器并置。我假设有效令牌总是在对安全资源请求的响应的授权标头中返回。这就是客户端获取新令牌的方式。我也没有提到与授权服务器的通信必须通过资源服务器,因为第一个需要 client_id 和 secret,客户端应用程序不能持有。我将编辑我的问题以明确说明。
      • 我希望这能消除你的疑虑stackoverflow.com/posts/27966775/revisions
      • 授权头是一个HTTP请求头。您不应该在回复中发送它。通常,访问令牌和刷新令牌都作为来自授权服务器的 JSON 响应返回。
      猜你喜欢
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      相关资源
      最近更新 更多