通过关键字直接搜索小程序源码得到关键部分:
if ("POST" === t) y.sign = r(d, m.url.replace(a.default.HOST, ""), p, v, S), m.data = d; else {
for (var h = m.url + "?", b = 0, w = Object.keys(d); b < w.length; b++) {
var P = w[b];
h += P + "=" + d[P] + "&";
}
h = h.substring(0, h.length - 1), m.url = h, y.sign = r({}, m.url.replace(a.default.HOST, ""), p, v, S);
}
我们看一下这2行代码的区别:
r(d, m.url.replace(a.default.HOST, ""), p, v, S)
r({}, m.url.replace(a.default.HOST, ""), p, v, S)
通过此处分析可以看到,如果t应该是存放的接口访问类型 POST/GET,如果是POST它调用的r函数的第一个参数是d,如果是GET则直接是{},由此得知d是一个post数据,连动态调试都没必要。
而r函数的实现过程则是一个拼接以及md5加密,如下方所示
function r(o, n, r, s, i) {
for (var u = "", c = 0, l = Object.keys(o).sort(); c < l.length; c++) {
var d = l[c], f = o[d];
if ("object" === e(f) && null !== f) {
var g = JSON.stringify(o[d]);
u += d + "=" + (g = g.split("").sort().join("")) + "&";
} else 0 === f || f ? u += d + "=" + o[d] + "&" : (o[d] = "", u += d + "=&");
}
return u += "url=" + n + "&", u += r ? "accessToken=" + r + "&" : "", u += "timestamp=" + s + "&",
u += "nonceStr=" + i + "&", u += "key=" + a.default.PLAM_KEY, t.md5Encrypt(u);
}
可以通过它的拼接猜出了这5个参数
1、post数据,如果是get则提交{}
2、url,但是是把host部分替换成空
3、r参数是accessToken,如果未登录状态应该是空的
4、v参数也很明显是一个timestamp时间戳,head里面也会包含
5、这个就是nonceStr,我们也需要知道这个参数是如何生成的。
nonceStr参数的由来
}, v = parseInt(String(new Date().getTime() / 1e3)), S = "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(e) {
var t = 16 * Math.random() | 0;
return ("x" == e ? t : 3 & t | 8).toString(16);
}), y = {
timestamp: v,
nonceStr: S
};
通过跟踪S参数发现,它显示固定赋值xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx,然后再通过正则把x和y替换成随机的 16数字并且转换成十六进制而已,这个直接复制来用就可以了
以下是最终封装的js代码:
function sign(postData, url, accessToken, timestamp, nonceStr) {
var PLAM_KEY = "ca235e27dcf94107889b9ad00ceebd48";
for (var u = "", c = 0, l = Object.keys(postData).sort(); c < l.length; c++) {
var d = l[c], f = postData[d];
if ("object" === e(f) && null !== f) {
var g = JSON.stringify(postData[d]);
u += d + "=" + (g = g.split("").sort().join("")) + "&";
} else 0 === f || f ? u += d + "=" + postData[d] + "&" : (postData[d] = "", u += d + "=&");
}
return u += "url=" + url + "&", u += accessToken ? "accessToken=" + accessToken + "&" : "", u += "timestamp=" + timestamp + "&",
u += "nonceStr=" + nonceStr + "&", u += "key=" + PLAM_KEY, t.md5Encrypt(u);
}
sign({},"index.php?/data=123","token",1600030304,"nonceStr~")