【问题标题】:What is the purpose of a "Refresh Token"?“刷新令牌”的目的是什么?
【发布时间】:2016-12-23 11:37:13
【问题描述】:

我有一个与 YouTube Live Streaming API 集成的程序。它在计时器上运行,因此对我来说,使用刷新令牌每 50 分钟获取一个新的访问令牌相对容易。我的问题是,为什么?

当我通过 YouTube 进行身份验证时,它给了我一个刷新令牌。然后,我使用此刷新令牌大约每小时获取一次新的访问令牌。如果我有刷新令牌,我总是可以使用它来获取新的访问令牌,因为它永不过期。所以我看不出这比从一开始就给我一个访问令牌而不打扰整个刷新令牌系统更安全。

【问题讨论】:

  • 访问令牌是 bearer 令牌。这意味着不需要其他身份证明,只需访问令牌即可冒充您。因此,它们应该始终保持短暂的存在。另一方面,刷新令牌不是 bearer 令牌。当您向 YouTube 发送刷新令牌以获取新的访问令牌时,您还必须发送 client_id 和 client_secret。因此,刷新令牌可以保持更长的寿命,因为刷新令牌和 client_secret 都不太可能被泄露。

标签: authentication oauth youtube-api access-token refresh-token


【解决方案1】:

基本上,刷新令牌用于获取新的访问令牌。

为了清楚区分这两个令牌并避免混淆,以下是The OAuth 2.0 Authorization Framework中给出的它们的功能:

  • 访问令牌由授权服务器在资源所有者的批准下颁发给第三方客户端。客户端使用访问令牌访问资源服务器托管的受保护资源。
  • 刷新令牌 是用于获取访问令牌的凭据。刷新令牌由授权服务器下发给客户端,用于在当前访问令牌失效或过期时获取新的访问令牌,或者获取范围相同或更窄的其他访问令牌。

现在,要回答您关于为什么仍然获得刷新令牌而不是仅仅保护访问令牌的问题,互联网工程任务组在Refresh tokens 中提供的主要原因是:

出于安全原因,refresh_token 只与授权服务器交换,而access_token 与资源服务器交换。这降低了长期 access_token 在“一个小时有效的访问令牌、一个一年有效的刷新令牌或直到撤销有效”与“一个访问令牌有效直到撤销但没有刷新”中泄漏的风险令牌。”

有关 OAuth 2.0 Flow 的更详细和完整的信息,请尝试阅读以下参考资料:

【讨论】:

  • 刷新令牌也应该有助于获取新的刷新令牌吗?
  • 为什么不获取一个新的短期访问令牌过期?如果您仍然需要向服务器请求新的 access_token,为什么还要拥有长寿命的 refresh_token?或者,如果使用 refresh_token,我不需要维护活动的身份提供者 cookie,并且即使在 cookie 早已消失之后,它也会根据 refresh_token 发出新的 access_tokens,如果用户想要获得一个,则必须输入他的凭据。新的 access_token?
  • @JustAMartin 作为 OAuth2 客户端,如果没有刷新令牌,我需要再次启动整个授权流程(让用户“登录”并再次授予我权限),以便获得另一个访问令牌。刷新令牌绕过此要求,作为我作为客户已经收到用户请求访问令牌的许可的一种“证明”。
  • 这个答案非常关注“什么”,而很少关注“为什么”。我认为一个真实的例子会让读者受益。
  • @Sammy Taylor 完全同意。我不敢相信我读了整面墙的文字只是为了一无所获
【解决方案2】:

刷新令牌至少有两个用途。首先,刷新令牌是一种“证明”,表明 OAuth2 客户端已经从用户那里获得了访问其数据的权限,因此可以再次请求新的访问令牌,而无需用户离开通过整个 OAuth2 流程。其次,与长期存在的访问令牌相比,它有助于提高整个安全流程。我将更详细地讨论这两点。

刷新令牌作为一种不惹恼用户的手段

让我们用一个例子来谈谈第一个目的。假设您是一名用户,正在使用想要与您的 YouTube 帐户数据进行交互的第三方客户端 Web 应用程序。一旦您授予客户端应用程序使用您的 YouTube 数据的权限,您是否希望客户端应用程序在其 YouTube 令牌过期时提示您再次获得您的许可?如果 YouTube 令牌的到期时间非常短,例如 5 分钟,会发生什么情况。让客户端应用程序至少每 5 分钟提示一次您的许可会有点烦人! OAuth2 针对这个“问题”提出的解决方案是刷新令牌。通过使用刷新令牌,访问令牌可以保持短暂的状态(如果访问令牌以某种方式泄露或被盗,这是可取的),并且刷新令牌可以保持较长(更)寿命,允许客户端获得新的访问权限令牌过期而不需要用户的许可(再次)。

但为什么是刷新令牌?如果重点是不通过权限请求来干扰用户,那么为什么客户端不能简单地说“嘿,授权服务器,我想要另一个访问令牌。现在!”?或者,“嘿授权服务器,这是我过期的令牌,给我一个新的!”。好吧,刷新令牌用作一种“证明”,即客户端在某个原始时间点被用户授予访问权限。这个“证明”是由授权服务器数字签名的刷新令牌的形式。通过客户端提供刷新令牌,授权服务器可以验证客户端是否在过去的某个时间收到了用户的许可,并且客户端不必再次提示用户。

刷新令牌以提高安全性

但是,这提出了一个问题,“好吧,如果刷新令牌被泄露或被盗,或者只是被恶意客户端应用程序保留而没有根据用户的请求删除它,会发生什么?攻击者不能吗?只是继续使用刷新令牌无限期地(或直到它过期)获得有效的访问令牌?这个问题导致讨论我提到的第二个目的,刷新令牌有助于更安全的流程。

访问令牌出现的问题是,一旦获得,它们只会呈现给资源服务器(例如 YouTube)。因此,如果访问令牌被盗或泄露,您如何告诉资源服务器不要信任该令牌?好吧,你真的不能。唯一的方法是更改​​授权服务器上的私有签名密钥(首先签署令牌的密钥)。我想这样做不方便,并且在某些情况下(如 Auth0)不受支持。

另一方面,刷新令牌需要经常提交给授权服务器,因此如果一个被泄露,那么撤销或拒绝整个刷新令牌是微不足道的,而不必更改任何签名密钥.

【讨论】:

  • 意思是不惹恼用户为我解释了这一点。在我的上下文中,我从 Web 后端访问 API,因此我不必手动输入凭据,它们在应用程序中可用。我一直在想,为什么不每次都用我的凭据获取一个新令牌,为什么要存储一个刷新令牌并跟踪它的过期时间。我从没想过在手动输入凭据的用户工作流程中,这会非常烦人。
【解决方案3】:

@Teyam 提到 SO 帖子为什么 OAuth v2 同时具有访问和刷新令牌?但我更喜欢那里的另一个答案:https://stackoverflow.com/a/12885823/254109

TL;DR refresh_token 不会带来更高的安全性。其目的是提高可扩展性和性能。然后,access_token 可能只存储在一些快速的临时存储(如内存)中。它也允许授权和资源服务器分离。

【讨论】:

  • 除非有安全原因,正如@Teyam 提到的那样:“refresh_token 只与授权服务器交换,而 access_token 与资源服务器交换”
  • 如果我们假设授权服务器作为资源服务器更安全,这只会更安全。如果不是这种情况,它实际上就不那么安全了。如果刷新令牌被泄露,我可以使用它来获取新的访问令牌。
  • TL;DR ??真的吗?
【解决方案4】:

“所以我看不出这比从一开始就给我一个访问令牌而不用打扰整个刷新令牌系统更安全。” 我在同一个问题上挣扎。简短的回答是刷新令牌是确保凭据没有过期所必需的。

一个例子可能会有所帮助: 我有一个存储您的医疗记录的数据库。您同意与您的配偶分享您的医疗记录。您的配偶使用他们的访问令牌从我的数据库中读取您的记录。两周后,您的配偶再次检查您的医疗记录,刷新令牌用于确保他们仍然有权(来自身份验证服务器)查看您的记录。刷新令牌绕过了您的配偶将其凭据(用户名和密码)重新输入到身份验证服务器的需要,但它确实确保了他们仍然具有访问资源的合法性。永不过期的访问令牌不会知道您是否撤销了配偶访问您的医疗记录的权利。

【讨论】:

  • 如果我撤销了配偶访问我的医疗记录的权利,即使它永不过期,访问令牌是否无效?
  • 访问令牌的寿命很短,通常在 30 到 60 分钟左右,并且极不可能有人向其数据(安全资源)授予客户端应用程序授权并在 30-60 分钟内撤销它。但是如果用户确实撤销了,那么授权服务器将撤销访问令牌和刷新令牌。此外,当接收者(在本例中为配偶)决定她/他不再需要访问受保护的资源时,一个好的客户端应用程序还应该自愿调用 /revoke 端点以放弃令牌。这样,当不再需要有效令牌时,它们就不会存在。
【解决方案5】:

这是来自OAuth 2.0 documentation的信息。

Refresh tokens 用于在当前访问令牌失效或过期时获取新的access token,或者获取范围相同或更窄的额外访问令牌(访问令牌的生命周期可能比授权者授权的时间更短,权限也更少)资源所有者)。

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

(A) 客户端通过身份验证请求访问令牌 授权服务器并提供授权。

(B) 授权服务器对客户端进行身份验证并验证 授权授予,如果有效,则颁发访问令牌 和一个刷新令牌。

(C) 客户端向资源发出受保护的资源请求 服务器通过提供访问令牌。

(D) 资源服务器验证访问令牌,如果有效, 处理请求。

(E) 重复步骤 (C) 和 (D) 直到访问令牌过期。如果 客户端知道访问令牌已过期,它跳到步骤(G); 否则,它会发出另一个受保护的资源请求。

(F) 由于访问令牌无效,资源服务器返回 无效令牌错误。

(G) 客户端通过身份验证请求新的访问令牌 授权服务器并提供刷新令牌。这 客户端身份验证要求基于客户端类型 以及授权服务器策略。

(H) 授权服务器对客户端进行身份验证并验证 刷新令牌,如果有效,则发出一个新的访问令牌(并且, (可选)一个新的刷新令牌)。

【讨论】:

    【解决方案6】:

    access_tokens 使用频率更高,由于它们的生命周期很短,因此撤销能力并不是很重要。

    refresh_tokens 使用频率较低,撤销能力至关重要,因为它们可用于生成新的access_tokens。

    验证签名令牌的成本较低,但撤销却很困难。

    验证存储在数据库中的令牌成本高昂,但很容易撤销。

    因此,签名密钥可以用作access_tokens 以提高性能。

    数据库存储的密钥可以用作refresh_tokens,以便于撤销它们。

    如果没有refresh_token,则很难找到一种提供低成本验证和易于撤销能力的机制。所以refresh_token存在是因为性能原因。

    【讨论】:

    • 这样假设是否也正确,因为刷新令牌在请求中的使用频率较低,它们被拦截的可能性也较小?
    【解决方案7】:

    拥有短期访问令牌和长期刷新令牌的原因至少有 3 个。

    不记名令牌

    来自原始问题:

    如果我有刷新令牌,我总是可以使用它来获取新的访问令牌,因为它永不过期。

    虽然可能总是能够使用刷新令牌获得新的访问令牌,但攻击者通常可能不会。这是因为您对刷新令牌的使用与您作为客户的身份证明相结合,例如通过提供您的 client_secret。访问令牌是不记名令牌,不需要这样的证明,即简单地展示它们就足够了。

    访问令牌是短暂的,这在一定程度上减轻了访问令牌的无限权力。

    攻击面

    访问令牌与(可能很多)资源服务器交换,这增加了泄漏的机会。刷新令牌只与授权服务器交换。

    同样,访问令牌的短暂性至少是某种程度的缓解措施。

    撤销

    将访问令牌实现为签名的 JWT 是可能的(并且很常见)。在这种情况下,任何服务器(知道签名方的公钥,通常位于某个众所周知的位置)都可以独立验证访问令牌的正确性。这允许很好地解耦架构,因为资源服务器不必向授权服务器询问授权。

    这种设置的缺点是无法撤销此类令牌(没有任何像撤销授权服务器的公钥这样激烈的事情)。

    通过使访问令牌的寿命短暂,可以简单地允许它们用完而不是显式撤销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 2017-01-18
      • 2021-12-21
      • 2023-04-08
      • 2019-03-25
      • 2021-04-07
      • 2021-08-08
      相关资源
      最近更新 更多