淘宝H5页面接口Sign签名破解
前言:由于公司业务需求,需要显示淘宝商品详情页面的图文详情部分。之前原业务逻辑是根据https://world.taobao.com/item/{num_iid}.htm
,在得到html文本后全量通过图片前缀名如https://img.alicdn.com/imgextra
进行抓取,返回给客户端。
由于header中的UA传的一个PC端的UA,所以获取的H5数据中,可能含有一些广告,商家之类自己的布局,从而无法在客户端正常展示。另一方面,该接口为高频接口,打开htm页面每次耗时70~80%,严重影响客户端体验,所以对此将接口进行升级。
后来发现手机上打开该页面是不显示一些无关的广告的,而且布局也正常。于是将UA改为了手机端的UA,然后通过抓包分析,返回的页面是一个不包含图片的html,图文详情是根据js接口调用动态渲染。接口为https://h5api.m.taobao.com/h5/mtop.wdetail.getitemdescx/4.9/?jsv=2.4.11&appKey=12574478&t=1544165283634&sign=c691925755f2ff429c950f7b00903a23&api=mtop.wdetail.getItemDescx&v=4.9&type=jsonp&dataType=jsonp&callback=mtopjsonp6&data=%7B%22item_num_id%22%3A%22554401452734%22%7D
。看到参数中包含了sign
,所以是根据某种规则算出来的签名。
接着就是找到sign
的签名算法了,将页面中的js格式化了一下。找到关于sign签名的部分。
1 | s.prototype.__processRequestUrl = function(n) { |
看到这里应该是一个加密后的js,后来找到一篇文章。淘宝sign加密算法。根据抓包的参数,按照公式来计算sign,验证算法是否正确。可能由于时间戳没有取整,或者一些其他的原因如编码问题等,导致sign的值没有和正确值对上,又看到文中贴的代码比我找到的js更加简单,以为淘宝更新了算法。再后来一位知友提示说算法没有问题,(在此特别感谢知友Jaho及文章作者小歪)才又抓包试了一次,这次将毫秒时间戳转为了int,并将字符串进行utf8编码,算出来的sign值和抓包中的匹配。后来证实通过js断点调试也可以验证公式的正确性。sign生成公式为:md5Hex(token&t&appKey&data)
t表示毫秒时间戳,appKey一般为固定值。data为参数。本文中的例子为6b2310e47a950f1c8c3fe6ec792f356a&1544165283634&12574478&{"item_num_id":"554401452734"}
再进行md5转换。
知道了sign算法,接下来就是token的获取,根据知乎文中作者所说,第一次请求是会设置cookie,于是使用Postman清理cookie后请求,此时sign的值传任何值均无影响,接口会返回
1 | mtopjsonp2({ |
并设置两个cookie,一个是_m_h5_tk
值为6b2310e47a950f1c8c3fe6ec792f356a_1544173923544
,另一个是_m_h5_tk_enc
,这个目前用不到,我们要的token就是前者_
分割的前部分。这样一来,我们请求两次接口,第一次拿到token,第二次请求拿到数据。
1 | { |
其中的images数组就是我想要的数据,这里返回值不是标准的json,套了一层mtopjsonp2({JSON}),于是获取结果后还要根据正则截取一下json的文本。
附上部分相关代码,python版本
1 | def get_images_from_mtop(num_iid): |
可以看到,接口响应时间有了大幅度提升。