前言

我零零总总用了好几个月的时间,写了一个自用的小程序,从 Aliexpress 上抓取订单的小程序。刚开始写的时候,该API还没有开放,而且没有订单相关的功能。我完全是通过模拟用户在网页上的操作来做的:获取网页源码,用正则取数据,然后组装到本地数据库。

期间经历过Ali 的数次微调,每次微调,我都要耗费几个小时做程序上的调整,最大的改动就是Ali 弄个新的 和 老的 订单展示页并存的时候。

最难的部分当数用户登陆部分,一次登陆,需要跨几个域,收集这几个域返回的 Cookie,收集好几个ajax返回的结果. Cookie 的问题,我用同一个 CookieContainer 解决了,但是 ajax 的,我还得老老实实的每个每个的按顺序去请求。

前两天,Ali 搞了一个小飞机,某状态下没有订单,分页居然有 2147483648 页,一看就是溢出了,正当我准备调整程序的时候,他们又神一般的把这个问题修复了。

数月前,我就申请成开发者账户,而且通过了,只是一直没有去研究。通过这次小飞机后,我决定,改用API获取订单数据,不在从网页抓取了。

开始

首先要注册成为开发者:

http://gw.api.alibaba.com/isv/index.htm

注册成功后,会分配给你一个应用的唯一标志:

其中:

Key 即为API 中说的 YOUR_APPKEY

签名串 即为 API 中说的YOUR_APPSECRET

API 说明可以打开如下地址:

http://gw.api.alibaba.com/dev/doc/sys_auth.htm?ns=aliexpress.open

获取授权步骤:

发起授权请求,用户同意授权后,返回 临时授权码,这里称为 Code

该步骤请求如下地址:

http://gw.api.alibaba.com/auth/authorize.htm?client_id=xxx&site=aliexpress&redirect_uri=urn:ietf:wg:oauth:2.0:oob

client_id 要填写 APPKEY

redirect_uri 是同意授权后回调的地址,因为我写的是客户端,不是WEB应用,所以当然没有回调地址,所以就用这个:urn:ietf:wg:oauth:2.0:oob

在请求之前,需要把上面的地址进行签名,把签名的值做为参数:_aop_signature的值,加到上面的地址里,一起请求,签名说明如下:

参数签名(_aop_signature)为所有参数key + value 字符串拼接后排序,把排序结果拼接为字符串data后通过bytesToHexString(HAMC-RSA1(data, appSecret))计算签名。验证签名的方式为对参数执行同样的签名,比较传入的签名结果和计算的结果是否一致,一致为验签通过。

注:只有客户端和WEB端授权流程发起授权请求这一步使用参数签名串组装规则,只用url请求参数作为签名因子;其他签名均需加入urlPath作为额外因子(见API签名串组装规则)。

Ali 给出了签名算法的C#示例:

http://gw.api.alibaba.com/dev/tools/app_signature.html

二,获取授权码

获取到临时码后,需要用 临时授权码 交换 授权码,所有的API都是通过授权码进行操作的

授权码获取地址:

https://gw.api.alibaba.com/openapi/http/1/system.oauth2/getToken/{0}?grant_type=authorization_code&need_refresh_token=true&client_id={1}&client_secret={2}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&code={3}

其中:

{0}处和{1}处填写 APPKEY

{2} 处填写 APPSECRET

{3}处填写上一步获取到的那个临时授权码 Code

need_refresh_token 如果为 false 的话,不会返回用于刷新授权码的刷新码(我叫它刷新码).

返回的结果如下:

{"aliId":"xxx","resource_owner":"xxx","expires_in":"36000","refresh_token":"xxx","access_token":"xxx"}

expires_in 是授权码的过期时间(秒),10个小时 (60 x 60 x 10)。如果过了10小时,就需要刷新授权码。

refresh_token 是后面需要用的刷新码

access_token 即新的授权码

三,刷新授权令牌

授权令牌自生成时间起,会在10小时后过期,这时如果在访问API,返回的是401 未授权。当该状况发生时,需要刷新授权令牌。刷新授权令牌 不需要 重新获取 临时码

请求地址:

https://gw.api.alibaba.com/openapi/param2/1/system.oauth2/getToken/{0}

POST 如下数据:

grant_type 值为固定的 refresh_token

client_id 值为 APPKEY

client_secret 值为APPSECRET

refresh_token 即上一步中获取的令牌中的刷新码(refhreshToken)

刷新授权令牌 得到的结果 和用 临时授权码 得到的 授权令牌 大致一致,但是少了刷新码,因为刷新码的有效期为半年。

其它说明

令牌的刷新码(refreshToken),在API文档中,说是半年有效期,但是在令牌中并没有关于刷新码的过期时间信息。

授权令牌的有效期为10分钟,也就是说即使你退出了应用,重新打开,只要你能复现这个授权令牌,在10分钟内,是不需要重新授权,重新获取授权码的。

所以,在用临时码或刷新码获取到授权码后,应该把相关信息存起来,以便下次使用,因为从本文最上面的图片中可以看到,API 每日最大的调用次数为 1W 次。

业务逻辑和结构逻辑分离

不知道我这样说有没有什么不妥。

API的每个方法调用都需要有授权令牌。但是如果在这些方法里都加上相关的 是否以授权,是否有授权令牌 的判断代码,相信连你自己都觉得不妥。

这里,我管API方法的调用叫业务逻辑,判断是否授权等叫结构逻辑。

做过MVC的一定知道,ActionFilter 很好用,可以将和业务无关的逻辑分离出来,但是C# 并没有原生的类似ActoinFilter 的东西。查了一下,有个叫PostSharp 的东西,但是这个东西不免费。

我之前用过EntLib ,对里面的 PIAB (策略注入 Policy Injecton) 了解一点点,但是仅局限于用配置文件做。因为这里的目的很明确:判断是否有授权,用配置文件做我觉得不妥。搜了一把,很多牛人都写过相关的文章,就是用 PolicyInjection.Create 和 PolicyInjection.Wrap 方法,并结合 ICallHandler 接口,及 HandlerAttribute 来做。

1     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
2 public class NeedAuthAttribute : HandlerAttribute {
3
4
5 public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container) {
6 return new NeedAuthHandler();
7 }
8 }
 1 public class NeedAuthHandler : ICallHandler {
2 public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) {
3 var opts = input.Target as APIOpts;
4 if(opts.AuthToken == null)
5 opts.Auth( opts.User , opts.Pwd);
6 if(opts.AuthToken.HasExpiressed)
7 opts.RefreshAccessToken();
8 return getNext()(input, getNext);
9 }
10
11
12 public int Order {
13 get;
14 set;
15 }
16 }
 

使用起来很简单,就是在需要做授权判断的方法上加上相关的 Attribute

1 [NeedAuth]
2 public OrderDetail FindOrderById(string orderNo) {
3 var url = this.GetApiUrl(OrderFindOrderByID)
4 .SetUrlKeyValue("orderId", orderNo);
5 var rh = new RequestHelper(this.CookieContainer);
6 var ctx = rh.Get(url);
7 return JsonConvert.DeserializeObject<OrderDetail>(ctx);
8 }

不过,上面的还不够,还需要在获取实例的时候:

1 private static APIOpts GetAPIOpts(string user, string pwd) {
2 var opts = AuthDataPersistence.Load(user);
3 if(opts == null)
4 opts = PolicyInjection.Create<APIOpts>(user, pwd);
5 else
6 opts = PolicyInjection.Wrap<APIOpts>(opts);
7 return opts;
8 }

好了,现在只需要在需要有授权的API方法上加上 NeedAuth 特性就行了,如果没有授权,就会自动去授权,如果需刷新授权码,就会自动刷新授权码,代码看起来清爽多了。

转载自:http://www.cnblogs.com/xling/p/3279373.html

Aliexpress API 授权流程整理(转载)的更多相关文章

  1. Aliexpress API 授权流程整理

    Aliexpress API 授权流程整理   前言 我零零总总用了好几个月的时间,写了一个自用的小程序,从 Aliexpress 上抓取订单的小程序.刚开始写的时候,该API还没有开放,而且没有订单 ...

  2. 高德地图API(流程法)整理分析

    [高德地图API(流程法)分析]: 前言:公司现在的网约车项目,使用的是高德地图,因为地图导航这一块的功能占比量比较大,为了方便大家对高德地图API的了解和学习使用,使用流程图把高德API分析整理了下 ...

  3. 基于SPA的网页授权流程(微信OAuth2)

    先说传统MVC网站的网页授权流程. 1.用户发起了某个需要登录执行的操作 2.收集AppId等信息重定向到微信服务器 3.微信服务器回调到网站某个Controller的Action 4.在此Actio ...

  4. Aliexpress API 测试工具

    Aliexpress API 测试工具 上回简单说了 Aliexpress API 的认证流程, 这回在奉送一个小工具, API 测试工具. 点我下载 做这一行,和做程序员的生活完全不搭调, 格格不入 ...

  5. spring cloud+dotnet core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

  6. spring cloud+.net core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

  7. HTML5 Geolocation API地理定位整理(一)

    HTML5 Geolocation API 用于获得用户的地理位置. 鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的. 浏览器支持 Internet Explorer 9+, ...

  8. OAuth 2.0 概念及授权流程梳理

    本文可以转载,但请注明出处https://www.cnblogs.com/hellxz/p/oauth2_process.html OAuth2 的概念 OAuth是一个关于授权的开放网络标准,OAu ...

  9. shiro框架学习-2-springboot整合shiro及Shiro认证授权流程

    1. 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

随机推荐

  1. jQuery之ajaxForm提交表单

      1.jQuery的设计非常优雅,其源代码亦给人以美感,利用jQuery框架写出来的js既简练又能完美跨浏览器.   2.jquery form插件是基于jQuery开发的一套能够利用ajax技术提 ...

  2. 使用vim-pathogen 进行插件管理

    使用vim的插件管理器 pathogen进行vim的插件管理. 1. pathogen 管理插件 pathogen让每个插件占有一个单独的目录,解决了文件分散的问题.安装完 pathogen之后,只需 ...

  3. android基础---->NDK的使用

    NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式.NDK将是Android平台支持C开发的开端,今天我们开始ndk的学习. NDK的简要说明 ndk是什么: The Nati ...

  4. 在腾讯云服务器上体验Docker

    版权声明:本文由姚俊刚原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/85 来源:腾云阁 https://www.qclou ...

  5. 高中生的IT之路-1.1自序

        近几年来越来越多的人问我关于 高中生要不要读大学.大学选择专业.毕业后的择业问题,索性我不如把我对这几方面的理解写出来,如果有幸能帮助到更多的人,那也算是个人对社会做出了一点贡献.       ...

  6. Egret3D初步学习笔记三 (角色使用)

    一 Unity中编辑角色 仍然使用unity4.7.1_Egret3D_Dll.unitypackage. 里面含有一个角色. 二 查看人物的动画 选中lingtong 属性面板里有个Animator ...

  7. {sharepoint}提升 SharePoint 代码执行权限

    提升 SharePoint 代码执行权限 关于如何提升 SharePoint 代码执行权限及相关知识介绍的文章我们园子里有很多, 这里给出其中两篇文章的链接,就不再啰嗦了. http://www.cn ...

  8. c# 计算文字高度

    SizeF sizeF = g.MeasureString(listBox1.Items[e.Index].ToString(), e.Font, listBox1.Width);

  9. Windows Phone 几种弹出框提示方式

    首先,我们需要在网络上下载一个Coding4Fun 然后,引用  using Coding4Fun.Phone.Controls.Toolkit;                using Codin ...

  10. django后台导入excel文件

    1.django 如何从后台上传excel中批量解析数据 要从django后台导入的excel中批量解析数据,举一个例子,我们向后抬批量导入svn历史数据数据格式 假设excel表中有4列,每列分别是 ...