Auth2.0
根据RFC6749协议介绍,Auth2.0是一个授权(官方用的是authorization,这里要注意授权authorization和认证authentication的区别)协议,它允许第三方应用通过Http Service来获取部分权限。
授权流程
RFC6749协议给出的授权流程图如下:
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
Figure 1: Abstract Protocol Flow
A. 第三方应用发起授权
B. 平台方弹出授权页面,页面显示授权范围
C. 用户同意授权,然后第三方应用去获取access_token
D. 平台方返回access_token
E. 然后第三方应用拿获取到的access_token去调用平台方api
F. 平台方返回资源
授权方式
授权码模式(Authorization Code)
Authorization Code方式是用的最多的一种方式,流程如下:
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
A. 第三方应用发起授权
B. 用户同意授权
C. 平台方重定向到事先约定好的URL,并在URL里附加上code参数
D. 第三方应用解析URL并做参数校验后,用code和在平台方生成的key和secret去换access_token
E. 平台方做校验后放回access_token
F. 第三方应用用拿到的access_token去获取用户授权的数据
与简化模式(Implicit)不同的是,Authorization Code获取access_token是在第三方应用的Server上进行的,因此access_token并不会暴露给浏览器或者客户端
简化模式(Implicit)
简化模式(Implicit)是授权码模式(Authorization Code)的简化版,是给用浏览器作为客户端的应用用的,流程图如下
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
密码模式(Resource Owner Password Credentials)
密码模式是将用户在平台上的账户密码提供给第三方应用,比如各种抢火车票的软件用的这种模式。这种认证模式的缺点显而易见。
客户端模式(Client Credentials)
客户端模式指客户端以自己的名义,向"服务提供商"进行认证
Authorization Request
response_type: 值必须设置为code,token或者其他约定的值
client_id: 平台方分给应用方的Id
redirect_uri(可选): 回调url,redirect_uri必须做严格限制,以Github为例
scope: 应用方申请的权限范围,这个是由平台方定义的
state: state的值建议设置为不可猜测的,其目的是防止csrf攻击
Authorization Response
code: 平台方传给应用方的code,应用方的在请求access_token的是有用到。code只能用一次。而且当code被使用多次的时候,平台方应当拒绝请求,并且回收所有已经分配的access_token(文档建议这么做,但实际上没见到有平台做这么严格)
state: 应用方传给平台方的state参数,平台方回回传给应用方。state是用来防止csrf攻击的,因此它的值是应该经过编码的,
refresh_token: refresh_token是可选的,当access_token过期时,可以用refresh_token去获取新的access_token