什么是 OAuth 2.0

OAuth 2.0 是一个行业的标准授权协议。OAuth 2.0 专注于简化客户端开发人员,同时为 Web 应用程序,桌面应用程序,手机和客厅设备提供特定的授权流程。

它的最终目的是为第三方应用颁发一个有时效性的令牌 token。使得第三方应用能够通过该令牌获取相关的资源。常见的场景就是:第三方登录。当你想要登录某个论坛,但没有账号,而这个论坛接入了如 QQ、Facebook 等登录功能,在你使用 QQ 登录的过程中就使用的 OAuth 2.0 协议。

角色

首先需要介绍的是 OAuth 2.0 协议中的一些角色,整个授权协议的流程都将围绕着这些角色:

  • resource owner,资源所有者,能够允许访问受保护资源的实体。如果是个人,被称为 end-user。
  • resource server,资源服务器,托管受保护资源的服务器。
  • client,客户端,使用资源所有者的授权代表资源所有者发起对受保护资源的请求的应用程序。如:web网站,移动应用等。
  • authorization server,授权服务器,能够向客户端颁发令牌。
  • user-agent,用户代理,帮助资源所有者与客户端沟通的工具,一般为 web 浏览器,移动 APP 等。

协议流程

  上图详细的描述了这四个角色之间的步骤流程:

  (A) Client 请求 Resource Owner 的授权。授权请求可以直接向 Resource Owner 请求,也可以通过 Authorization Server 间接的进行。

  (B) Client 获得授权许可。

  (C) Client 向 Authorization Server 请求访问令牌。

  (D) Authorization Server 验证授权许可,如果有效则颁发访问令牌。

  (E) Client 通过访问令牌从 Resource Server 请求受保护资源。

  (F) Resource Server 验证访问令牌,有效则响应请求。

授权

一个客户端想要获得授权,就需要先到服务商那注册你的应用。一般需要你提供下面这些信息:

  • 应用名称

  • 应用网站

  • 重定向 URI 或回调 URL(redirect_uri)

  • 重定向 URI 是服务商在用户授权(或拒绝)应用程序之后重定向用户的地址,因此也是用于处理授权代码或访问令牌的应用程序的一部分。

在你注册成功之后,你会从服务商那获取到你的应用相关的信息:

  • 客户端标识 client_id

  • 客户端密钥 client_secret

  • client_id用来表识客户端(公开),client_secret用来验证客户端身份(保密)。

授权类型

  OAuth 2.0 列举了四种授权类型,分别用于不同的场景:

  • Authorization Code(授权码 code):服务器与客户端配合使用。

  • Implicit(隐式 token):用于移动应用程序或 Web 应用程序(在用户设备上运行的应用程序)。

  • Resource Owner Password Credentials(资源所有者密码凭证 password):资源所有者和客户端之间具有高度信任时(例如,客户端是设备的操作系统的一部分,或者是一个高度特权应用程序),以及当其他授权许可类型(例如授权码)不可用时被使用。

  • Client Credentials(客户端证书 client_credentials):当客户端代表自己表演(客户端也是资源所有者)或者基于与授权服务器事先商定的授权请求对受保护资源的访问权限时,客户端凭据被用作为授权许可。

  下面来具体说说这四种授权。注意重定向一定要用 302。

授权码模式

  该方式需要资源服务器的参与,应用场景大概是:

  • 资源拥有者(用户)需要登录客户端(APP),他选择了第三方登录。

  • 客户端(APP)重定向到第三方授权服务器。此时客户端携带了客户端标识(client_id),那么第三方就知道这是哪个客户端,资源拥有者确定(拒绝)授权后需要重定向到哪里。

  • 用户确认授权,客户端(APP)被重定向到注册时给定的 URI,并携带了第三方给定的 code。

  • 在重定向的过程中,客户端拿到 code 与client_id、client_secret去授权服务器请求令牌,如果成功,直接请求资源服务器获取资源,整个过程,用户代理是不会拿到令牌 token 的。

  • 客户端(APP)拿到令牌 token 后就可以向第三方的资源服务器请求资源了。

隐式模式

  该方式一般用于移动客户端或网页客户端。隐式授权类似于授权码授权,但 token 被返回给用户代理再转发到客户端(APP),因此它可能会暴露给用户和用户设备上的其它客户端(APP)。此外,此流程不会对客户端(APP)的身份进行身份验证,并且依赖重定向 URI(已在服务商中注册)来实现此目的。

  基本原理:要求用户授权应用程序,然后授权服务器将访问令牌传回给用户代理,用户代理将其传递给客户端。

资源所有者密码模式

  用户将其服务凭证(用户名和密码)直接提供给客户端,该客户端使用凭据从服务获取访问令牌。如果其它方式不可行,则只应在授权服务器上启用该授权类型。此外,只有在客户端受到用户信任时才能使用它(例如,它由服务商自有,或用户的桌面操作系统)。

客户端模式

这种模式只需要提供client_id和client_secret即可获取授权。一般用于后端 API 的相关操作。

POST 请求客户端凭证流程:

字段 描述
grant_type 必须,必须设置到客户端证书中。
scope 可选,授权的作用域。

  返回值

  1. {
  2. "access_token" : "...", "token_type" : "...", "expires_in" : "...",
  3. }

  如果授权服务器验证成功,那么将直接返回令牌 token,改客户端已被授权。

作者:网教通  创建时间:2019-08-30 21:17
 更新时间:2023-11-14 10:57