OAuth协议解决的问题

假设我们开发了一个第三方应用助手,这个助手的功能是为了读取和美化微信用户的自拍数据,此时我们该怎么办?直接让微信把自拍数据发给我们是不可能的。那我们可以让用户把微信的用户名密码发给我们,但是先不说用户愿不愿意给,就算用户把用户名密码给我们了,那我们使用它去微信里拿用户的自拍数据也是存在很大的问题的:

  • 应用可以访问用户在微信上的所有数据
  • 用户只有修改密码,才能收回授权,但是如果这个用户还给除助手以外的第三方应用也授权,密码一改,所有的第三方应用都无法使用用户的数据了
  • 密码泄露的可能性大大提高
    20200223221714

而OAuth协议就是为了解决这些问题而诞生的,用户不需要将用户名密码给应用,而是交给应用一个令牌
20200223221831
我们可以在令牌上规定应用所能访问的信息;令牌上会有一个有效期,到期后则再也无法访问用户的数据了。

OAuth协议中的各种角色

  • 服务提供商Provider
    • 认证服务器Authorization Server,用于生成令牌(Token)
    • 资源服务器Resource Server,保存用户数据和验证令牌
  • 资源所有者Resource Owner,即用户,但资源在应用上。如微信
  • 第三方应用Client,如我们的应用助手

20200223222712

  • 0.微信用户首先访问我们的第三方应用Client(角色)
  • 1.Client向资源所有者(角色)请求授权,也就是微信用户
  • 2.资源所有者同意授权
  • 3.Client得到同意授权后,向服务提供商申请令牌,服务提供商也是一个角色,但是服务提供商里面有认证服务器和资源服务器,认证服务器专门负责发送Token,资源服务器负责验证Token和开放资源,在这里的步骤中只是到认证服务器中申请令牌
  • 4.认证服务器发放令牌给Client
  • 5.Client拿着令牌到资源服务器去做验证,并申请用户的自拍数据
  • 6.资源服务器验证后,开放资源给Client

这就是OAuth协议,但是其中最最关键的就是第2步骤,同意授权,这也是所有流程中最复杂的一个地方。目前的授权模式有4个:

  • 1.授权码模式(功能最完整,流程最严密的一种方式,常用)
  • 2.简化模式
  • 3.密码模式
  • 4.客户端模式

OAuth协议运行流程

重点讲解一下授权码模式,如下图所示:
20200223223935

  • 0.用户访问Client
  • 1.如果Client需要用户授权,则Client会将用户导向认证服务器
  • 2.用户同意授权的动作会在认证服务器上来完成
  • 3.如果用户同意授权,按照和第三方Client之前的约定,认证服务器会将用户重新导回刀Client上(某个约定好的url),并携带授权码,注意此时返回的不是Token,而是一个授权码
  • 4.Client应用得到授权码后,会用这个授权码去向认证服务器申请令牌,这一步是在Cilent应用的后台服务器上完成的,对用户不可见
  • 5.认证服务器会核对第四步申请令牌中携带的授权码是不是第三步自己发过去的,如果是确认无误,则发放令牌

在其他的三种模式里是没有授权码这个东西的,所以它叫授权码模式,该模式有两个特点将它和其他三种授权模式区分开来:

  • 用户同意授权的动作是在认证服务器上完成的。而其他的授权模式都是在第三方应用上完成的,完成授权后,第三方应用去向服务器申请令牌的时候带着一些信息告知认证服务器用户已授权给我,请同意我访问用户数据。但这时候,认证服务器没法确定用户是不是真的给应用授权了,有可能授权信息是第三方应用伪造的。而在授权码模式下,认证服务器可以明确的知道用户确实同意了授权
  • 在用户同意授权,从认证服务器返回第三方应用的时候,携带的并不是最终的令牌,而是一个授权码,第三方应用还需拿着这个授权码去认证服务器换取令牌,这就要求第三方应用必须要有一个服务器才能发送这个请求。而有些静态网站是没有服务器的,这种网站就需要使用四种模式中的简化模式,在认证服务器返回到第三方应用的时候直接携带的就是令牌,静态页面用脚本读取返回的令牌。

Finally

⭐Actions speak louder than words.