最开始接触 OAuth2.0 的时候,经常将它和 SSO单点登录搞混。后来因为工作需要,在项目中实现了一套SSO,通过对SSO的逐渐了解,也把它和OAuth2.0区分开了。所以当时自己也整理了一篇文章《SSO单点登录原理及实现方式》
最近需要经常和各大电商平台进行对接,所以又和OAuth2.0重逢了。因此这里再次对OAuth2.0的原理及实现方式进行一个梳理,希望通过这套教程能够帮到大家。对于技术类的文章,这引言是有点过长了。好了下面我们进入正题。
什么是 OAuth2.0
OAuth 是一种开放的授权协议,它是目前最流行的授权机制。它允许将存储在一个站点上的资源共享到另一个站点,而无需使用该站点的凭据。
这类定义一般都比较抽象,要理解起来不是太容易。所以这里我们通过一个实际应用的类比来说明一下这个场景,你会发现,其实OAuth2.0的原理并不复杂。
首先,假设我在微信上注册了账号,然后加了一些好友,并且有一些聊天记录。
然后,我正在访问一个网站/应用。这里假设正在访问 www.jiyik.com 。这个网站有一项功能是可以获取微信号上的好友和聊天,然后对这些信息进行一个统计分析的功能(当然,本站是没有这项功能的)。
个人感觉这项功能不错,就想使用它。有一种方式是我可以把个人的微信账号和密码告诉这个应用。应用可以通过账号密码获取到好友信息和聊天记录。但是这样我感觉很不安全,如果我以后不想再继续使用了,那我还得再去修改账号和密码。那样就会很麻烦了。所以这里就需要一种方式可以使得我将一些权限授权给该网站,使其可以不用账号和密码就可以获取到这些信息。 这种授权方式就是 OAuth2.0。当我不再想使用该功能的时候,我就可以把权限收回或者使授权失效。
所以说一个完整的OAuth2.0 的流程需要涉及到三个实体。
- 资源服务商 (微信,Google,Facebook等)
- 第三方网站/应用
- 用户
当有另一个第三方的网站要使用微信账号登录其系统时,同样我们也可以通过授权的方式登录这个第三方的网站。这样就实现了同一个微信账号可以多个不同的网站进行登录。这也是一种单点登录,这也是为什么最初经常会将其和SSO单点登录搞混的原因。
通过上面的场景,我们大概也能清楚OAuth2.0的基本的原理了。下面我们通过整体介绍一下其架构,来更深入的了解其工作原理。
OAuth2.0 架构
整个的流程是这样的。
一、 首先,用户使用 Google、微信 等第三方应用程序访问资源。
二、 第三方网站会带着客户端ID和客户端密钥重定向到资源服务的授权登录界面。
三、 用户会接收到一个Google或微信的授权登录界面。用户需要在该界面进行授权。
四、 用户使用身份验证应用程序登录。客户端 ID 和客户端密钥对于授权服务器上的客户端应用程序是唯一的。
五、 身份验证服务器使用授权代码将用户重定向到重定向统一资源标识符 (URI)。这个地址是第三方网站在接入资源服务的认证服务时提交给认证服务的,当用户授权成功后,会被重定向到该网址。
六、 用户访问位于客户端应用程序中重定向 URI 的页面,该页面此时会带有一个用于验证的Code。
七、 客户端应用程序将获得身份验证Code、客户端 ID 和客户端密钥,并将它们发送到授权服务器。
八、 身份验证应用程序向客户端应用程序返回访问令牌。
九、 一旦客户端应用程序获得访问令牌,用户开始使用客户端应用程序访问资源所有者的资源。
整个OAuth2.0的流程就是这样的。这其中会涉及到一些HTTP的知识点,关于HTTP可以参考我们的 HTTP教程。
OAuth2.0会涉及到很多术语和概念,下面我们对这些术语概念进行一些解释。
术语
验证
身份验证是识别一个用户的过程,通常是基于用户个人的用户名和密码。通过用户名和密码来验证该用户是否是一个合法的资源持有者。
联合身份验证
许多第三方网站/应用都有自己的用户名和密码。某些应用程序依赖于其他服务来验证用户的身份。联合身份管理系统提供对多个系统的单一访问。这称为联合身份验证。
授权
授权是允许某人做某事的过程。它需要有效用户的身份来检查该用户是否被授权。
委托授权
委托授权是将自己的凭据提供给其他用户以代表该用户执行某些操作的过程。
角色
OAuth 定义了以下角色
- 资源所有者 - 资源所有者被定义为能够授予访问其在资源服务器上托管的自己数据的能力的实体。当资源所有者是个人时,称为最终用户。
- 客户端应用程序 - 客户端是一个应用程序,它发出受保护的资源请求以代表资源所有者执行操作。
- 资源服务器 - 资源服务器是可用于访问用户信息的 API 服务器。
- 认证服务器 - 认证服务器从资源所有者那里获得许可并将访问令牌分发给客户端,以访问由资源服务器托管的受保护资源。
Web 服务器
Web 服务器是一个计算机系统,它使用 HTTP协议 将网页传送给用户。只要应用程序想要访问资源服务器,客户端ID和密钥就存储在web应用程序服务器上。将客户端ID和密钥存储在 Web 应用程序服务器上的目的是保密。
在上图中,资源所有者允许机密客户端访问托管在资源服务器上的数据,其中客户端 ID 和密钥保存在服务器上并且是保密的。
客户端 ID 和密钥对于授权服务器上的客户端应用程序是唯一的。
资源服务器是一个服务器,它承载着 Google、微信等资源。这些资源存储在资源服务器上,供客户端应用程序访问,资源所有者拥有这些资源。
然后,授权服务器使用客户端 Web 应用程序访问资源所有者的资源。
用户代理
用户代理应用程序由用户设备中的客户端应用程序使用,它可以是一个脚本语言,例如在浏览器中运行的 JavaScript。所以说我们可以将用户代理应用程序存储在 Web 服务器上。
下图显示了客户端用户代理应用程序的架构。
一、 首先,用户使用 Google、微信 等身份验证应用程序访问资源所有者的资源。
二、 接下来,用户应用程序提供客户端 ID 和客户端密钥,从而登录到授权服务器。
三、 然后,用户代理应用程序提供一个在浏览器中运行的 JavaScript 应用程序实例并链接到 Web 服务器。
四、 授权服务器允许使用客户端凭据从资源服务器访问资源。
五、 资源服务器包含由资源所有者拥有的资源。
本机应用程序
本机应用程序可以用作桌面或手机应用程序的实例,它使用资源所有者凭据。它是安装在资源所有者设备上的客户端应用程序。
应用程序使用的身份验证凭据包含在应用程序代码中。因此,不要使用在外部用户代理中运行的本机应用程序。
一、 首先,用户使用 Google、微信 等身份验证应用程序访问资源所有者的资源。
二、 接下来,本机应用程序使用客户端 ID 和客户端密钥登录到授权服务器。本机应用程序是桌面或手机应用程序的实例,它安装在用户计算机上,并将客户端密钥存储在计算机或设备上。
三、 授权服务器允许使用客户端凭据从资源服务器访问资源。
四、 资源服务器包含由资源所有者拥有的资源。
总结
以上我们介绍了OAuth2.0 的整体流程,以及这中间涉及到的一些术语和概念我们分别进行了介绍。这要求我们对 HTTP协议 的原理要稍微有些了解。通过上面的介绍其实我们可以看到,整个过程较为核心的部分就是对 访问令牌的获取。