我目前正在编写一些代码来处理 oAuth(使用 Azure Graph API,但我认为 Google API 类似)。
要进行 API 调用,我需要一个访问令牌,其有效期约为一小时。要获取访问令牌,我需要先让用户授权我的应用使用,这将产生一个授权码,其有效期约为十分钟。在获取访问令牌的同时,我还可以获得一个刷新令牌,其有效期通常为 90 天。不过,我可以在刷新令牌过期之前获取新的刷新令牌,以确保我保留有效的刷新令牌。
所以有三种类型的代码/令牌需要处理。
为什么需要所有这些不同的代码和令牌?为什么不直接提供一个有效期为 90 天的授权码就可以了呢?
我是否正确地假设,如果我的刷新令牌过期,那么我必须回到链的开头并再次向我的用户请求访问权限?
答案1
为什么需要所有这些不同的代码和令牌?为什么不直接提供一个有效期为 90 天的授权码就可以了呢?
授权代码是传递访问令牌的几种方式之一——它不是一个单独的“步骤”,但仍然是初始“交互式身份验证”流程的一部分。它与实际访问令牌的不同之处在于,您还需要 OAuth2 客户端密钥(或开始时生成的 PKCE 质询)才能使用该代码。理论上,这意味着即使代码本身被拦截(例如通过客户端可见的重定向),也只有原始应用程序可以将其交换为真实令牌。
还有其他流程不使用令牌 - 例如,您可以使用“隐式授予”流程直接接收访问令牌,或者您可以使用证书进行身份验证并在一个步骤中接收令牌,具体取决于 OAuth IDP 支持的内容。
(例如,Google 中的“服务帐户”使用 RSA 密钥对进行身份验证以获取访问令牌 - 它们不使用交互式身份验证流程,因此没有身份验证代码。)
我是否正确地假设,如果我的刷新令牌过期,那么我必须回到链的开头并再次向我的用户请求访问权限?
是的,但避免这种情况实际上是刷新令牌的目的。
如果您只有一种类型的令牌(访问令牌),每次令牌过期时,您都需要回到链的开头。通常可以通过使用刷新令牌来避免这种情况,刷新令牌通常具有更久,更长生命周期,例如,如果访问令牌的有效期为几个小时或几天,则刷新令牌的有效期通常为几个月或几年。
我想说的是,90 天的刷新令牌有效期异常短,而且在某种程度上违背了拥有刷新令牌的意义——我猜 Azure OAuth2 是专门这样设置的,以便通过更难窃取的凭据强制重新认证,例如设备证书或“Windows Hello”使用的自定义 HMAC 方案。(相比之下,谷歌颁发的刷新令牌似乎几乎没有有效期——多年来我一直使用同一个令牌访问 Gmail IMAP。)
答案2
因为它们有不同的用途,所以有不同的类型。拥有它们的一个简单原因是,它们可能会被破坏并用于不同的目的。因此,让它们短暂存在可以确保不当处理或受损的客户端虽然仍然很糟糕,但可能造成的影响较小。
区分什么功能也很有用。一个 token 意味着你只需要拿到一个 token 就可以做所有事情。拥有多个 token 会让你更难获得做所有事情的选项。
看RFC 6749有关令牌类型的更多信息。