写点什么

玩转 ApiFox 脚本实现自动化

作者:Liam
  • 2022 年 9 月 16 日
    广东
  • 本文字数:2544 字

    阅读完需:约 8 分钟

前言:之前做一个京东联盟的自动化脚本,好多人不理解为什么,这次做淘宝的自动化签名,并讲解一下实现细节,带你了解前置脚本,后置脚本的用法。

自动化原理

个人观点自动化就像流水线一样,通过解析固定的规则,来达到自动化。

前置和后置脚本的区别(它们的功能就如同名字一样)

前置脚本:在请求发送之前,你可以通过脚本来做某些事情,值得注意的是变量是在前置脚本后面才执行的,所有有些问题可能不是你问题。


前置脚本:在请求响应之前,你可以通过脚本来做某些事情。



淘宝联盟接入文档

调用入口

调用 API 的服务 URL 地址,开放平台目前提供了 2 个环境给 ISV 使用:正式环境,海外环境。


公共参数

调用任何一个 API 都必须传入的参数,目前支持的公共参数有:


签名算法

为了防止 API 调用过程中被黑客恶意篡改,调用任何一个 API 都需要携带签名,TOP 服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。TOP 目前支持的签名算法有三种:MD5(sign_method=md5),HMAC_MD5(sign_method=hmac),HMAC_SHA256(sign_method=hmac-sha256),签名大体过程如下:


  1. 对所有 API 请求参数(包括公共参数和业务参数,但除去 sign 参数和 byte[]类型的参数),根据参数名称的 ASCII 码表的顺序排序。如:foo:1, bar:2, foo_bar:3, foobar:4 排序后的顺序是 bar:2, foo:1, foo_bar:3, foobar:4。

  2. 将排序好的参数名和参数值拼装在一起,根据上面的示例得到的结果为:bar2foo1foo_bar3foobar4。

  3. 把拼装好的字符串采用 utf-8 编码,使用签名算法对编码后的字节流进行摘要。如果使用 MD5 算法,则需要在拼装的字符串前后加上 app 的 secret 后,再进行摘要,如:md5(secret+bar2foo1foo_bar3foobar4+secret);如果使用 HMAC_MD5 算法,则需要用 app 的 secret 初始化摘要算法后,再进行摘要,如:hmac_md5(bar2foo1foo_bar3foobar4)。

  4. 将摘要得到的字节流结果使用十六进制表示,如:hex("helloworld".getBytes("utf-8")) = "68656C6C6F776F726C64"


说明:MD5 和 HMAC_MD5 都是 128 位长度的摘要算法,用 16 进制表示,一个十六进制的字符能表示 4 个位,所以签名后的字符串长度固定为 32 个十六进制字符。

调用示例

以 taobao.item.seller.get 调用为例,具体步骤如下:


  1. 设置参数值


公共参数:


method=taobao.item.seller.getapp_key=12345678session=testtimestamp=2016-01-01 12:00:00format=jsonv=2.0sign_method=md5 业务参数:


fields=num_iid,title,nick,price,numnum_iid=11223344


  1. 按 ASCII 顺序排序(去掉等号)


app_key12345678fieldsnum_iid,title,nick,price,numformatjsonmethodtaobao.item.seller.getnum_iid11223344sessiontestsign_methodmd5timestamp2016-01-01 12:00:00v2.0


  1. 拼接参数名与参数值


app_key12345678fieldsnum_iid,title,nick,price,numformatjsonmethodtaobao.item.seller.getnum_iid11223344sessiontestsign_methodmd5timestamp2016-01-01 12:00:00v2.0


  1. 生成签名假设 app 的 secret 为 helloworld,则签名结果为:hex(md5(helloworld+按顺序拼接好的参数名与参数值+helloworld)) = "66987CB115214E59E6EC978214934FB8"

  2. 组装 HTTP 请求将所有参数名和参数值采用 utf-8 进行 URL 编码(参数顺序可随意,但必须要包括签名参数),然后通过 GET 或 POST(含 byte[]类型参数)发起请求,如:


http://gw.api.taobao.com/router/rest?method=taobao.item.seller.get&app_key=12345678&session=test&timestamp=2016-01-01+12%3A00%3A00&format=json&v=2.0&sign_method=md5&fields=num_iid%2Ctitle%2Cnick%2Cprice%2Cnum&num_iid=11223344&sign=66987CB115214E59E6EC978214934FB8

配置环境参数

设置全局变量

AppKey 和 AppSecret


设置相关环境下的服务器地址

开始分析参数指定规则

通过调用示例我们可以知道所有的参数都在 url 中,也就是说参数存在于 Query 参数中。


  1. 公共参数必选有:method ,app_key ,timestamp ,v ,sign_method ,sign 。


app_key:可以使用全局变量 。v:可以固定为 2.0sign_method:可以固定:hmac,md5,hmac-sha256 其中一个


  1. 此时需要处理的公共参数有:method,timestamp ,sign 。


method:使用正常 Query 参数 timestamp :通过脚本处理 sign :通过脚本处理


  1. 业务参数使用 body 参数中来处理。

添加接口

这里以:淘宝客-公用-淘口令生成,来作为示例。


业务请求和响应参数



添加 Query 参数



添加 Body 参数和响应参数


使用前置脚本处理

//定义公共参数let params = new Map([    ["method", pm.request.url.query.get("method")],    ["app_key", pm.globals.get("app_key")],    ["timestamp", getTimestamp()],    ["v", "2.0"],    ["sign_method", "md5"],    ["format", "json"]])
//业务参数pm.request.body.urlencoded.each(item => { params.set(item.key, item.value);})
//获取时间function getTimestamp() {
let zero = function (number) { if (number > 10) return number; return `0${number}`; }
let date = new Date(); let timestamp = { year: date.getFullYear(), month: zero(date.getMonth() + 1), date: zero(date.getDate()), hour: zero(date.getHours()), minute: zero(date.getMinutes()), second: zero(date.getSeconds()) } return `${timestamp.year}-${timestamp.month}-${timestamp.date} ${timestamp.hour}:${timestamp.minute}:${timestamp.second}`;}
//签名封装function signature([...params]) { let stringToBeSigned = pm.globals.get("app_secret"); params.sort(); params.forEach(([key, value]) => { stringToBeSigned += `${key}${value}` }); stringToBeSigned += pm.globals.get("app_secret"); return CryptoJS.MD5(stringToBeSigned).toString().toUpperCase();}
//参数会重组,这里先移除pm.request.url.query.remove("method");
//重组参数pm.request.body.urlencoded = [];params.forEach((value,key) => { pm.request.body.urlencoded.add({ key: key, value: value })})
//添加签名参数pm.request.body.urlencoded.add({ key: "sign", value: signature(params)})
复制代码


可以去官网下载操作一下:www.apifox.cn

用户头像

Liam

关注

没有一个bug是无辜的! 2021.12.23 加入

一个简单的程序员!

评论

发布
暂无评论
玩转ApiFox脚本实现自动化_测试_Liam_InfoQ写作社区