摘要:最近公司应公司需求,对天猫精灵对接进行了一番探索,回头看整个过程并不复杂,但是有些细节做好的话,会走很多的弯路,这篇文章记录一下过程中的遇上问题以及个人解决的方案,如果有不合适的地方希望大家积极指出。
认识Oanth2.0
认识一个新的事物,个人认为最快的方式是度娘和实践;一个度娘不行,就多个度娘,一点点的集中关键点;这个过程很头大……废话不多说;
初步认识oauth2.0是看了大神的一篇文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html,里面介绍的还是比较详细的,但是都是表面的东西;
主要是我记录一下是;AliGenie平台的认证使用的是其中的 - 授权码模式;
个人觉得阿里选用这种方式也是意料之中的事情,主要因为授权码模式是(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。
这种认证模式的基本模型是:
流程其实很简单:
- 用户访问客户端,后者将前者导向认证服务器。
- 用户选择是否给予客户端授权。
- 假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
- 客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
- 认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
这些流程代码中其实基本已经实现完成,我们做的只是需要简单的配置;
A步骤中,客户端申请认证的URI,包含以下参数:
- response_type:表示授权类型,必选项,此处的值固定为"code"
- client_id:表示客户端的ID,必选项
- redirect_uri:表示重定向URI,可选项
- scope:表示申请的权限范围,可选项
- state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
例如:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
C步骤中,服务器回应客户端的URI,包含以下参数:
- code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
- state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
例如:
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
重点:在这一步中AliGenie平台中发送的数据中 redirect_uri 这个参数后面带有自己的参数,整体是以urlEncode后传递过来的,这样的话开始我们就发现整个过程有些奇怪,最后发现这些扯淡的东西根本不用管,应该是AliGenie平台自己做标示用的,这些参数在回调时直接带上就是了;
接下来就是client(AliGenie平台获取到code,它会拿到code去认证服务器获取access_token)
D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:
- grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
- code:表示上一步获得的授权码,必选项。
- redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
- client_id:表示客户端ID,必选项。
重点:这一步主要是获取access_token,主要有两种方式:
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 在header中添加一个基本授权
表单提交模式:最访问参数中添加&client_id=***&client_secret=****(AliGenie是以这样方式进行提交的)
解决方法:在Oauthserver配置中允许表单提交 allowFormAuthenticationForClients()
之后就可以顺利获取到ossecc_token
数据交互
认证完成之后Aligenie平台会先发送获取设备的命令,但是这个指令符合access——token认证方式,换句话说,就是一个普通的https接口调用;但是json的数据中带有access——token数据;
也就是说接下来我们不能直接使用资源服务器对接(这点我也感觉很蛋疼),不知道为什么,有知道的希望告知;