@liuliang520500/pdd-sdk
Version:
拼多多开放平台SDK,支持多多进宝API
150 lines (127 loc) • 5.66 kB
JavaScript
/**
* 拼多多开放平台签名验证示例
*
* 使用官方文档提供的示例参数验证签名算法
* 期望的签名结果: E4DE3ED21002510DED352819E7AE6775
*/
const crypto = require('crypto-js');
const nodeCrypto = require('crypto');
const fs = require('fs');
/**
* 拼多多签名生成函数
*
* 签名规则:
* 1. 将参数按照键名升序排序
* 2. 在参数前后加上clientSecret
* 3. 对整个字符串计算MD5并转为大写
*
* @param {String} clientSecret 应用密钥
* @param {Object} params 请求参数
* @return {String} 签名值
*/
function generateSign(clientSecret, params) {
// 按键名升序排序
const keys = Object.keys(params).sort();
// 拼接参数字符串
let stringToSign = clientSecret;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// 签名不包含sign字段本身
if (key !== 'sign' && params[key] !== undefined && params[key] !== null) {
stringToSign += key + params[key];
}
}
stringToSign += clientSecret;
// 记录签名过程
const output = [];
output.push(`排序后的键名: ${keys.join(', ')}`);
output.push(`拼接后的字符串: ${stringToSign}`);
// 计算MD5并转为大写
const sign = crypto.MD5(stringToSign).toString().toUpperCase();
output.push(`计算出的签名: ${sign}`);
fs.appendFileSync('signature-debug.log', output.join('\n') + '\n\n');
return sign;
}
// 基于官方文档的测试案例
function testOfficialExample() {
console.log('======= 拼多多开放平台签名验证 =======');
// 清空日志文件
fs.writeFileSync('signature-debug.log', '');
// 基于文档截图的示例参数
const testCase1 = {
clientSecret: '12345678', // 之前测试例子中的密钥
params: {
'type': 'pdd.ddk.oauth.goods.pid.generate',
'client_id': '89f9722aecac48d9a4363270cd4bd8e0',
'timestamp': '1499858290807',
'number': '1',
'p_id_name_list': '[123,456]',
'data_type': 'JSON',
'version': 'V1'
}
};
console.log('测试参数1:', JSON.stringify(testCase1.params, null, 2));
console.log('ClientSecret:', testCase1.clientSecret);
// 计算签名
const sign1 = generateSign(testCase1.clientSecret, testCase1.params);
console.log('生成的签名:', sign1);
console.log('是否匹配期望的签名:', sign1 === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配');
console.log('\n======= 官方文档的测试例子 =======');
// 官方文档中提供的测试参数和签名
const testCase2 = {
clientSecret: 'testSecret', // 官方文档中的密钥
params: {
'access_token': 'asd78172s8ds9a921j9qqwda12312w1w21211',
'client_id': '1',
'data_type': 'XML',
'type': 'pdd.order.number.list.get',
'timestamp': '1480411125',
'order_status': '1',
'page': '1',
'page_size': '10'
}
};
console.log('测试参数2:', JSON.stringify(testCase2.params, null, 2));
console.log('ClientSecret:', testCase2.clientSecret);
// 计算签名
const sign2 = generateSign(testCase2.clientSecret, testCase2.params);
console.log('生成的签名:', sign2);
console.log('期望的签名:', 'E4DE3ED21002510DED352819E7AE6775');
console.log('签名是否匹配:', sign2 === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配');
// 如果签名不匹配,进行特定测试
if (sign2 !== 'E4DE3ED21002510DED352819E7AE6775') {
console.log('\n尝试使用原生Node crypto库进行验证:');
// 使用Node.js原生crypto库测试
const stringToSign = 'testSecret' +
'access_token' + 'asd78172s8ds9a921j9qqwda12312w1w21211' +
'client_id' + '1' +
'data_type' + 'XML' +
'order_status' + '1' +
'page' + '1' +
'page_size' + '10' +
'timestamp' + '1480411125' +
'type' + 'pdd.order.number.list.get' +
'testSecret';
const nodeSign = nodeCrypto
.createHash('md5')
.update(stringToSign)
.digest('hex')
.toUpperCase();
console.log('拼接字符串:', stringToSign);
console.log('Node crypto签名:', nodeSign);
console.log('是否匹配:', nodeSign === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配');
// 测试官方提供的完整字符串
console.log('\n使用官方文档提供的完整拼接字符串测试:');
const officialString = 'testSecretaccess_tokenasd78172s8ds9a921j9qqwda12312w1w21211client_id1data_typeXMLorder_status1page1page_size10timestamp1480411125typepdd.order.number.list.gettestSecret';
const officialSign = nodeCrypto
.createHash('md5')
.update(officialString)
.digest('hex')
.toUpperCase();
console.log('官方拼接字符串:', officialString);
console.log('使用官方字符串生成签名:', officialSign);
console.log('是否匹配:', officialSign === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配');
}
}
// 执行测试
testOfficialExample();