oauth2.0 协议简记

缘起

组内有人分享Oauth2.0 协议. 本来就做过微信端开发. 所以为了巩固,还是听了一下,讲师分享了两个blog. 【1】是jenkov大神的,【2】是Oauth2.0 的RFC文档.

分析

首先Oauth2.0 常见于平常登录第三方应用(譬如天天酷跑游戏的服务端,或者是在微服务日益盛行中的网关)使用微信登录/QQ登录/微博登录. 即像下面这样

Oauth2.0协议中涉及的角色有

Client Application 就是我们用的第三方应用(的服务端)。

Resource Owner 能给Client Application 的对象的东西有以下四种类型

  • Authorization Code
  • Implicit
  • Resource Owner Password Credentials
  • Client Credentials

其中第一种和第四种是最常用的. 事实上,微信中用的就是这两种.

其中第一种的图示就是

可以说看懂了上面的图(其实就是微信开发授权网页的逻辑),就理解了Oauth2.0 的第一种Grant(授权).

第二种是什么呢? 第二种就是第一种中,Authentication Server 直接将token(即所谓的令牌)丢给浏览器(或者App客户端)而不是仅仅丢一个code给客户端,客户端发送code给Client Application, Client Application 再用这个code向Authentication Server获取token缓存起来. 继而客户端和Client Application 之间交互的仅仅是类似于session-cookie. 显然,由Client Application维护token是有好处的. 因为这个token太重要了,交由(不可信赖的)客户端是不安全的. 因为token是调用Resource Server(接口服务)的凭证. 所以由Client Application和Resource Server 之间交互token远比客户端和Resource Server 之间交互token安全的多. 正是因为这种原因,第二种Authentication Grant 几乎不用了. 但是第二种出现于 Oauth2.0协议未出现的早期. 所以作为历史文物保留了下来.

第三种就更简单了,相当于是Client Application 自己做了一个登陆页面,然后未登录的用户访问Client Application 会被导引到这个登陆页面. 然后填写自己的用户名密码,点击登陆按钮之后,用户名/密码就被发送到Authentication Server 去,Authentication Server 做一个校验,判断此用户能否登陆. 返回给Client Application 类似于true/false的结果, 然后用户登录. 这种设计相当于是把 Authentication Server 纯粹当做了一个UC(User Center), 这么做至少有两点不妥.

  1. 权限细粒度控制无法实现. 相当于是一旦用户名密码对了,我就可以让他访问所有的接口. 而第一种方式可以实现细粒度权限控制.
  2. 扩展性差. 因为接入一个Client Application 我就要让Authentication Server 认识他的用户群体.
  3. 让用户在明文的html页面上留下自己的账号密码信息是极度不安全的做法.

基于上述三点原因,第三种用的也非常少.

第四种就是微信开发中的逻辑(注意,不是微信授权网页的开发,微信授权网页开发用的oauth协议是第一种)——即你要调用我微信的接口是吧? 可以,拿access_token来, 而access_token怎么来? 是用户通过微信分配给你的 appid+appsecret 来获取的. 所以微信开发一般调用微信接口前都要先调用根据appid+appsecret获取access_token的接口先获取access_token,再使用该access_token 进行相应接口的调用. access_token 并不是永久的, 而是会过期的. 所以申请access_token的时候会返回相应的refresh_token(而且一般refresh_token的寿命都比access_token长不少,下次调用接口access_token失效了,可以通过refresh_token先获取新的access_token,再调接口)

参考

【1】http://tutorials.jenkov.com/oauth2/authorization.html

【2】https://tools.ietf.org/html/rfc6749#section-1.3.1

【2】https://tools.ietf.org/html/rfc6749#section-1.3.1