OAuth 授权流程

警告
本文最后更新于 2022-07-08,文中内容可能已过时。

OAuth 2.0 定义了四个流程来获取访问令牌。这些流程称为授权类型。决定哪一种适合您的情况主要取决于您的应用程序类型。

  • Authorization Code Flow:授权码流程是在已有用户的情况下运行,首先客户端将用户重定向到认证服务器身份验证页面。用户输入凭据信息进行身份验证。如果验证成功,认证服务器生成授权码并将其返回给客户端。之后,客户端使用此授权码请求访问令牌,并且认证服务器验证此请求是否有效。如果请求有效,则发送访问令牌。
  • Implicit Flow with Form Post:隐式流程具有相似的步骤和目标,但是它不涉及授权码的使用。该流程通常用于客户端应用程序(如JavaScript应用程序)和 Web 应用程序。在此流程中,客户端通过浏览器将用户重定向到认证服务器并请求访问令牌。然后,认证服务器弹出单独的窗口,用户在其中提供凭据。最终,上次请求将响应返回给客户端,包括访问令牌等。
  • Resource Owner Password Flow:资源所有者密码流通过将用户的用户名和密码作为凭证传递给认证服务器来获得访问令牌。这种方法适用于受信任的应用程序,如官方移动应用程序。尽管这是一种简单而直接的方法,但不建议或使用。因为它涉及将用户的凭据传输到客户端,存在风险。
  • Client Credentials Flow:客户端凭证流被设计用于机器到机器通信场景,其中客户端要访问由OAuth2 保护的资源。在此流程中,客户端使用其自己的凭据(client_id和client_secret)向认证服务器请求令牌。没有用户参与此流程

在授权流程中有 4 个角色

  • 资源所有者(Resource Owner):可以授予对受保护资源的访问权限的实体。通常,这是最终用户。
  • 资源服务器(Resource Server):托管受保护资源的服务器。这是您要访问的 API。
  • 客户端(Client):代表资源所有者请求访问受保护资源的应用程序。
  • 授权服务器(Authorization Server):对资源所有者进行身份验证并在获得适当授权后颁发访问令牌的服务器。

开始进行授权过程以前,第三方应用先要到授权服务器上进行注册。所谓注册,是指向认证服务器提供一个授权回调URL(redirect_url),然后从授权服务器中获取 Client ID(app_id)Client secrets(app_secret) ,以便能够顺利完成如下授权过程。

假设你在 Github 上创建了一个 Hugo 的 Blog 仓库,现在你想使用 Cloudflare Pages 功能部署你的 Blog。那 Cloudflare 需要访问你的 Blog 仓库,现在我们来看看这个流程。

如何防止其他应用冒充第三方应用骗取授权?

第三方应用的验证方式需要 ClientID 作为标识符,它是一个公开信息。与此同时,ClientSecret 是秘密信息,只有应用本身知道。在发放令牌时,必须提供这个秘密信息才能验证第三方应用的真实性。因此,保护好 ClientSecret 对于应用的安全至关重要,如果得不到保护,就会有人冒充其它应用程序进行攻击和非法访问。

为什么要先发放授权码,再用授权码换令牌

这是因为客户端转向(通常是HTTP 302重定向)对于用户是可见的,也就是说,授权码可能会暴露给用户及其机器上的其他程序。但由于用户无法获得 ClientSecret,授权码本身并不能直接换取到访问令牌。所以,这种设计可以避免令牌在传输转向过程中被泄漏的安全风险。

为什么要设计一个时限较长的刷新令牌和时限较短的访问令牌?实现方式和优缺点是什么?

Access Token 作为验证令牌,因为泄露、攻击等各种原因导致令牌失效的情况可能随时发生,减少其有效时间可有效缓解该问题。同时,刷新令牌 Refresh Token 具有更长的有效期,但仍然需要一定的时效性把握,以满足动态调整许可范围等需求。