基于oAuth的授权登陆( 二 )


  • 「用户」基于浏览器访问「客户端」,「客户端」重定向到「认证服务器」对应页面,引导的参数上会附带一个「重定向URI」,指向的是「客户端」页
  • 「用户」选择是否授权
  • 授权后,「认证服务器」根据「重定向URI」将浏览器引导回「客户端」页,同时会附带一个授权码
  • 「客户端」接收到授权码后,通过后台服务器,携带这个授权码以及「重定向URL」,向「认证服务器」申请令牌
  • 「认证服务器」校验无误后,向「客户端」发送令牌(AccessToken)和更新令牌(RefreshToken)
更新令牌(RefreshToken)的作用下文说明
简化模式(Implicit Grant)
基于oAuth的授权登陆

文章插图
 
简化模式不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤 。所有步骤在浏览器中完成,令牌对用户是可见的,且客户端不需要认证 。具体流程如下:
  • 「用户」基于浏览器访问「客户端」,「客户端」重定向到「认证服务器」对应页面,引导的参数上会附带一个「重定向URI」,指向的是「客户端」页
  • 「用户」选择是否授权
  • 授权后,「认证服务器」根据「重定向URI」将浏览器引导回「客户端」页,在URI的Fragment中会附带访问令牌
  • 「客户端」浏览器根据指令向「Web Hosted Client Resource」发送请求,该请求不包括上一步收到的Fragment,浏览器本地保存Fragment
  • 「Web Hosted Client Resource」返回一个网页(通常是一个包含脚本的网页,如果你理解JSONP,应该比较容易理解),这段脚本是可以从Fragment中解析出访问令牌的
  • 浏览器执行脚本获取令牌
  • 浏览器将令牌发放给客户端
密码模式(Resource Owner Password Credentials Grant)
基于oAuth的授权登陆

文章插图
 
相对于上面两种授权模式,密码模式相对的不安全,因为用户需要向客户端提供自己的用户名和密码 。客户端使用这些信息,向"服务商提供商"索要授权 。虽然协议里规定客户端不能存储账号密码,不过除非你非常信任客户端,否则应该不会使用这种模式 。
这种授权模式的具体流程如下:
  • 「用户」向「客户端」提供用户名和密码
  • 「客户端」将用户名和密码发送给「认证服务器」,请求令牌
  • 「认证服务器」验证后,返回访问令牌
客户端模式(Client Credentials Grant)
基于oAuth的授权登陆

文章插图
 
客户端模式下,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务 。具体流程如下:
  • 「客户端」向「认证服务器」进行身份认证,并要求一个访问令牌
  • 「认证服务器」验证后,返回访问令牌
更新令牌在上面的流程中,认证服务器认证后返回的数据,除了访问令牌,还有一个更新令牌 。我们知道了,通过访问令牌我们才能够访问资源,那更新令牌是做什么用的呢?
我们都知道,一般网站登录会有一个超时时间,这里也不例外 。访问令牌也有一个超时时间 。更新令牌就是用于在访问令牌过期后来获取新的访问令牌的 。
基于oAuth的授权登陆

文章插图
 
  • 「客户端」向「授权服务器」进行认证,获取access token 。
  • 「授权服务器」验证「客户端」后,发放访问令牌和刷新令牌 。
  • 「客户端」携带访问令牌向「资源服务器」请求资源
  • 「资源服务器」验证访问令牌,如果有效,则提供服务 。
  • 重复步骤3和4直到访问令牌到期
  • 当访问令牌无效,「资源服务器」返回无效的令牌错误
  • 「客户端」向授权服务器进行身份验证,并携带刷新令牌来请求新的访问令牌
  • 「授权服务器」验证「客户端」身份以及刷新令牌,如果有效,则发出新的访问令牌(以及可选的新刷新令牌)
最后补充在上面的流程中,实际还缺少了一步,就是注册客户端 。如果你接过微信、微博或QQ的授权登陆,那么应该清楚,在开始接入之前,我们需要在他们的开放平台上申请我们的应用,申请成功后会给我们一个AppId和一个appSecrect 。
这个的appId就是用来唯一确定客户端的 。而appSecrect就是在授权模式中,客户端的后台与授权服务器交互时需要连同code,appId一起提供的,用于置换访问令牌的 。


推荐阅读