Closed cncolder closed 5 years ago
贴在这里警示后来者!
alipayPublicKey
是指支付宝公钥, 而非checkNotifySign
之前删除 sign_type
, 而 checkNotifySign
函数内部又需要根据 sign_type
判断验签类型, 所以你的应用密钥需要使用 'RSA2', 或者自己写 checkNotifySign
函数.@cncolder alipayPublicKey 是指支付宝公钥 说明里写的是清楚的,但是sdk的checkNotifySign 却是错的,他们居然没有测试。delete signArgs.sign_type; 加上这句就正常了。
checkNotifySign(postData) {
const signStr = postData.sign;
const signType = postData.sign_type || 'RSA2';
if (!this.config.alipayPublicKey || !signStr) {
return false;
}
const signArgs = Object.assign({}, postData);
// 除去sign 皆是待验签的参数。
delete signArgs.sign;
delete signArgs.sign_type; //这里是增加的。。。。。。。!!!!!!!
const decodeSign = Object.keys(signArgs).sort().filter(val => val).map((key) => {
let value = signArgs[key];
if (Array.prototype.toString.call(value) !== '[object String]') {
value = JSON.stringify(value);
}
return `${key}=${decodeURIComponent(value)}`;
}).join('&');
const verifier = crypto.createVerify(util_1.ALIPAY_ALGORITHM_MAPPING[signType]);
verifier.update(decodeSign, 'utf8');
return verifier.verify(this.config.alipayPublicKey, signStr, 'base64');
}```
@cncolder 我看了他们更新日志,本来是有这一行的,结果,他们更新 Fixed: 修复通知校验签名失败
的时候删除了,然后就真的永远失败了。。真是有意思。。这么严谨的事,居然连测试都没有。
@zqqq 据说是为了修复沙箱环境, 我没测试.
@cncolder 我看了java的sdk 分getSignCheckContentV1 和 getSignCheckContentV2 看这个nodejs的是按v2来的。。估计文档哪里有写 版本区别吧。。
public static String getSignCheckContentV1(Map<String, String> params) {
if (params == null) {
return null;
}
params.remove("sign");
params.remove("sign_type");
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
content.append((i == 0 ? "" : "&") + key + "=" + value);
}
return content.toString();
}
public static String getSignCheckContentV2(Map<String, String> params) {
if (params == null) {
return null;
}
params.remove("sign");
StringBuffer content = new StringBuffer();
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
content.append((i == 0 ? "" : "&") + key + "=" + value);
}
return content.toString();
}
`
这个问题也花了我一个小时多,这里需要修改sdk,把 sign_type 给 delete 掉就好了。
加上 delete signArgs.sign_type; //这里是增加的。。。。。。。!!!!!!! 终于输出为true了 可以更新版本了,也不能老是改SDK
正式环境下, 各种尝试, 返回值永远都是
false
.默认配置传入 3 个参数:
appId
privateKey
alipayPublicKey
做过以下尝试:
signType
或keyType
.postData
中的sign_type
.subject
.body
.postData 如下:
目前只能是采用
mapi
接口验证notify_id
的单一方式来验证通知的真实性.