OAuth 2.0 介绍

OAuth为应用提供了一种访问受保护资源的方法。在应用访问受保护资源之前,它必须先从资源拥有者处获取授权(访问许可),然后用访问许可交换访问令牌(代表许可的作用域、持续时间和其它属性)。

下面介绍3种获取Access Token的方式:

A.Authorization Code:Web Server Flow,适用于所有有Server端配合的应用。

B.Implicit Grant:User-Agent Flow,适用于所有无Server端配合的应用。

C.Refresh Token:令牌刷新方式,适用于所有有Server端配合的应用。

使用Authorization Code获取Access Token

授权码是通过将用户引导到授权服务器而获得的一种访问许可。授权服务器验证用户,获得授权,然后向应用分发一个授权码。因为终端用户只在授权服务器上进行验证,所以终端用户的密码从来不用分享给应用。

当应用通过一个user-agent同用户进行交互的时候,授权码访问许可的方式是很合适的。 t01c30f88cf3bf33a84.png

图1所示的授权码获取流程包含下列步骤:

A.应用调用javascript的window.open()弹出窗口,并在该窗口将用户的user-agent引导到授权服务器的用户授权endpoint来发起这个流程。客户端传入标识符、请求作用域、本地状态,和一个重定向URI(在访问被许可或被拒绝后授权服务器会重新将user-agent引导回这个URI)。

B.授权服务器验证用户的身份(通过user-agent),并且确定用户是许可还是拒绝了应用的访问请求。

C.如果访问被许可,授权服务器会使用重定向URI将user-agent引导回应用。授权服务器传回一个授权码给应用,用于进一步获取访问令牌。如果用户选择拒绝授权,user-agent将关闭此弹出窗口。

2.1.2、获取Authorization Code

请求参数:

参数名必选介绍
client_idTrue创建应用时获得的App Key
response_typeTrue此值固定为“code”
redirect_uriFalse授权后要回调的URI,即接收Authorization Code的URI, 其值可以是“oob”。 非“oob”值的redirect_uri所在域名必须与开发者注册应用时所提供的回调地址的域名相匹配
scopeFalse以空格分隔的权限列表,若不传递此参数,代表请求默认的basic权限。(目前只有basic权限)
stateFalse用于保持请求和回调的状态,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),会在Query Parameter中原样回传该参数
   

请求示例:

https://openapi.360.cn/oauth2/authorize?client_id=0fb2676d5007f123756d1c1b4b5968bc&response_type=code&redirect_uri=http://www.example.com/oauth_redirect&scope=basic&display=default 

授权服务器会根据应用传递参数的不同,为用户展现不同的授权页面。如果用户在此页面同意授权,授权服务则将重定向用户浏览器到指定的“redirect_uri”,并附带上表示授权服务所分配的Authorization Code的code参数,以及state参数(如果请求authorization code时带了这个参数)。

例如:继续上面的例子,假设授权服务在用户同意授权后生成的Authorization Code为“120653f48687763d6ddc486fdce6b51c383c7ee544e6e5eab“,则授权服务将会返回如下响应包以重定向用户浏览器到“http://www.example.com/oauth_redirect”地址上:

返回示例:

HTTP/1.1 200 OK Location: http://www.example.com/oauth_redirect? state=&code=120653f48687763d6ddc486fdce6b51c383c7ee544e6e5eab 

说明:

A. “code”参数可以在“redirect_uri”对应的应用后端程序中获取。

B. 每一个Authorization Code的有效期为30秒,并且只能使用一次,再次使用将无效。

2.1.3、通过Authorization Code获取Access Token

通过上面第一步获得Authorization Code后,便可以用其换取一个Access Token。

请求参数:

参数名必选介绍
grant_typeTrue此值固定为“authorization_code”
codeTrue通过上面第一步所获得的Authorization Code
client_idTrue应用的App Key
client_secretTrue应用的App Secret
redirect_uriTrueredirect_uri所在域名必须与开发者注册应用时所提供的回调地址的域名相匹配

请求示例:

https://openapi.360.cn/oauth2/access_token?grant_type=authorization_code&code=120653f48687763d6ddc486fdce6b51c383c7ee544e6e5eab&client_id=0fb2676d5007f123756d1c1b4b5968bc&client_secret=8d9e3305c1ab18384f562d7d3f3b5179&redirect_uri=http://www.example.com/oauth_redirect 

返回参数:

若参数无误,服务器将返回一段JSON文本,包含以下参数

参数名必选介绍
access_tokenTrue获取的Access Token
expires_inTrueAccess Token的有效期,以秒为单位
refresh_tokenTrue用于刷新Access Token 的 Refresh Token
scopeTrueAccess Token最终的访问范围,即用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限)

返回示例:

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store {   "access_token":"120652e586871bb6bbcd1c7b77818fb9c95d92f9e0b735873",   "expires_in":"3600",   "scope":"basic",   "refresh_token":"12065961868762ec8ab911a3089a7ebdf11f8264d5836fd41" } 

2.2、使用Implicit_Grant获取Access_Token

2.2.1、简介

采用Implicit Grant方式获取Access Token的授权验证流程又被称为User-Agent Flow,适用于所有无Server端配合的应用(由于应用往往位于一个User Agent里,如浏览器里面,因此这类应用在某些平台下又被称为Client-Side Application),如手机/桌面客户端程序、浏览器插件等,以及基于JavaScript等脚本语言实现的应用,他们的一个共同特点是,应用无法妥善保管其应用密钥(App Secret),如果采取Authorization Code模式,则会存在泄漏其应用密钥的可能性。其流程示意图如下:

t010baa26dd4dd48f83.png

2.2.2、获取Access Token

为了获取Access Token,应用需要将用户浏览器(或手机/桌面应用中的浏览器组件)引导到360应用开放平台OAuth2.0授权服务的“https://openapi.360.cn/oauth2/authorize”地址上,并带上以下参数:

参数名必选介绍
client_idTrue获取的Access Token
response_typeTrue此值固定为“token”
redirect_uriFalse授权后要回调的URI,即接受code的URI, 其值可以是“oob”。 非“oob”值的redirect_uri所在域名必须与开发者注册应用时所提供的回调地址的域名相匹配
scopeFalse以空格分隔的权限列表,若不传递此参数,代表请求默认的basic权限。(目前只有basic权限)
stateFalse用于保持请求和回调的状态,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),会在Query Parameter中原样回传该参数
displayFalse登录和授权页面的展现样式,PC应用请传递“desktop”,默认为“page”,手机应用请传递mobile.default

例如:“client_id”为“ 0fb2676d5007f123756d1c1b4b5968bc”的应用要请求某个用户的默认权限,并在授权后需跳转到“http://www.example.com/oauth_redirect”,同时希望在弹出窗口中展现用户登录授权界面,则应用需要重定向用户浏览器到如下URL:

https://openapi.360.cn/oauth2/authorize?client_id=0fb2676d5007f123756d1c1b4b5968bc&response_type=token&redirect_uri=http://www.example.com/oauth_redirect&scope=basic&display=default 

返回参数:

参数名必选介绍
access_tokenTrue要获取的Access Token
expires_inTrueAccess Token的有效期,以秒为单位
stateFalse如果请求获取Access Token时带有state参数,则将该参数原样返回

返回示例:

HTTP/1.1 200 OK Location: http://www.example.com/oauth_redirect?state=# access_token=120652e586871bb6bbcd1c7b77818fb9c95d92f9e0b735873& expires_in=3600 

2.3、使用Refresh_Token获取Access_Token

2.3.1、简介

360应用开放平台的应用无论通过OAuth2.0哪种方式获取Access Token,都会拿到有效期为14天的Refresh Token,和一个小时有效期的Access Token。对于这些应用,只要用户在14天内登录,应用就可以使用Refresh Token获得新的Access Token。

2.3.2、获取Access Token

要使用Refresh Token获得新的Access Token,需要应用在其服务端发送请求(推荐用POST方法)到360开放平台OAuth2.0授权服务的以下地址: “https://openapi.360.cn/oauth2/access_token”,并带上以下参数:

参数名必选介绍
grant_typeTrue必须为“refresh_token”
refresh_tokenTrue用于刷新Access Token用的Refresh Token
client_idTrue应用的App Key
client_secretTrue应用的App Secret
scopeFalse以空格分隔的权限列表,若不传递此参数,代表请求默认的basic权限。注:通过Refresh Token刷新Access Token时所要求的scope权限范围必须小于等于上次获取Access Token时授予的权限范围

请求示例:

https://openapi.360.cn/oauth2/access_token?grant_type=refresh_token&refresh_token=12065961868762ec8ab911a3089a7ebdf11f8264d5836fd41&client_id=0fb2676d5007f123756d1c1b4b5968bc&client_secret=8d9e3305c1ab18384f562d7d3f3b5179&scope=basic 

若请求成功服务器将返回一段JSON文本,包含以下参数

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store {   "access_token":"120652e586871bb6bbcd1c7b77818fb9c95d92f9e0b735873",   "expires_in":"3600",   "scope":"basic",   "refresh_token":"12065961868762ec8ab911a3089a7ebdf11f8264d5836fd41 "} 

3、使用OAuth2.0调用API

获取access_token以后,就可以使用OAuth2.0调用API接口,有以下3种方法。

3.1、使用URL传递验证参数

在调用API的URL中传递需要的参数,如下(参数的详细介绍请参照API文档):

https://openapi.360.cn/user/me.json?access_token=120652e586871bb6bbcd1c7b77818fb9c95d92f9e0b735873

3.2、在header里传递验证参数

在header里添加Authorization:OAuth2空格Access Token的值。

Authorization: Oauth2 120652e586871bb6bbcd1c7b77818fb9c95d92f9e0b735873 

3.3、在Post中传递验证参数

在post传递的参数中加上Access Token。

access_token=120652e586871bb6bbcd1c7b77818fb9c95d92f9e0b735873



为什么要有2.0版本?

前面的文章说了OAuth1.0,怎么又突然冒出一个2.0呢?我查阅了一些文档,主要是这些原因:

1. 签名算法太复杂

还记得1.0里面需要对一堆必须的参数排序,编码,然后用secret去签名吧

2. 获取token的方式单一

就一种方式

3. 性能和可伸缩性比较差

由于验证和受保护资源都在一台服务器上。(这个。。。感觉有点牵强,应该也可以分离的)

2.0的改进

针对以上问题,2.0做了以下改进:

1. 角色分离

将认证服务器和资源服务器分开,功能更加清晰,性能和可伸缩性也更好。

2. 去除签名

对,任何签名都不需要了。但必须使用HTTPS安全通道。

3. 多种获取token的方式

a) 认证码授权(Authorization Code Grant )

1.0的简化版,客户端需要引导用户跳转到授权服务器提供的授权页面,用户输入密码,同意授权,授权服务器返回给客户端认证码,客户端用认证码去验证服务器换取访问码(Access Token)。

流程图,用新浪的:

b) 隐式授权(Implicit Grant)

客户端javascript获得资源的一种方式,一次请求即直接获取token。

c) 用户密码对授权(Resource Owner Password Credentials Grant)

用户在完全信任第三方客户端的情况下,把密码提供给客户端,客户端到认证服务器一次性换取访问码(Access Token)。

还有其他的一些方式了,具体可参考RFC。

4. 访问码(Access Token)过期

2.0里,访问码(Access Token)会有过期时间,但过期之后,客户端可以它换取新的访问码(Access Token),这样设计被认为安全。


在OAuth2流程中有2个载体,3个过程,4个角色:

         两个载体:

         Authorization Code, Access Token(refresh token)

         三个过程:

         用户认证,应用认证,用户授权

         四个角色:

         用户,应用,授权服务器,资源服务器

 

第一个改变发生在角色的拆分:将授权服务器和资源服务器拆分开来。将授权与资源访问的宿主由一一对应变成了一对多的方式,只要资源访问能够验证授权,那么任何授权服务点都可以成为该类资源的授权中心。其实也是为多种平台间互联互通技术的提供更灵活的支持,另一方面针对不同终端的授权也可以定制化流程,只要最终授权流程得到的结果可以被资源提供者所认可就行。

第二个改变发生在获取Access Token的过程,简化了一次交换Token的流程。我至今还不是很清楚折腾反复那么多次交换的用处。

第三个,对于Agent和Client的模式有了更明确的流程支持。C/S模式和纯JS模式都是没有一个可以推送授权结果服务端的问题,现在流程中利用在URL参数中增加#在带上业务参数不会被302从定向提交给服务端来解决安全性和数据获取的问题。

第四个,提高开发者的授权开发门槛,降低开发服务请求门槛。可以想象的到授权本身的调用量和使用比例要远小于服务调用量。原先对于三个过程中的应用认证主要发生在服务调用中,每次调用都要对参数作签名(由于参数的复杂性及调用次数很多,入口很多,导致开发查错难),而现在应用认证和用户授权都发生在授权流程中,完全剥离了资源访问者对应用认证的处理,增加了授权开发成本,却降低了服务调用成本。(其实这种设计大量被用在前后端设计优化中)

另一些小细节也显示出了这是开放平台人做的标准:CSRF攻击的预防(增加了State字段),允许应用身份登陆(操作一些应用相关的平台型服务),scope来扩展业务访问控制范围,expires time表示Token的有效期(原来都是无限长时间的)

 

http://huoding.com/2011/11/08/126

http://www.rollingcode.org/blog/f/oauth-core-1.0-final-cn.html

http://tools.ietf.org/id/draft-ietf-oauth-v2-31.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值