AdonisJs后端服务对接外部接口BA认证之node JS实现
官方对接的文档只有JAVA、php、python的实现案例,并没有js的实现版本,后面经过不断的摸索及测试验证,成功对接通过,现把相关的代码共享一下,有需要的同学可以参与,大家有更好的方法也可以给我留言,期待共同进步~
生成签名方法实现
/**
* 生成签名
* @param {String} data 待加密字符串
* @param {String} key 公共秘钥
*/
const genSign = (data,key) => {
// 第一个参数为加密字符串,第二个参数为公共秘钥
var hash = CryptoJS.HmacSHA1(data, key);
var base64 = CryptoJS.enc.Base64.stringify(hash);
return base64.toString();
}
验证签名方法实现
/**
* 验证签名
* @param {Object} request 请求
* @param {Object} response 响应
*/
const checkSign = ({request, response}) => {
let clientId = Env.get('CLIENTID');
let clientSecret = Env.get('CLIENTSECRET');
let date = request.headers.date;
let authorization = request.headers.authorization;
let stringToSign = request.method + " " + request.url + "\n" + date;
//console.log(stringToSign);
if (!authorization || !date) {
return false;
}
const currSign = genSign(stringToSign,clientSecret);
let checkAuth = "MWS " + clientId + ":" + currSign;
//console.log(checkAuth);
return checkAuth == authorization;
}
因对方订单号orderId入参是int19位,直接使用JSON.parse会造成精度丢失,17位之后的数字变成0,可以引入以下代码解决
import JSONbig from 'json-bigint'
console.log(JSONbig.parse(str));
返参的orderId也要是int19位并且是json字串,一开始使用JSONbig.stringify处理后,orderId并没有在json字串中显示,后面将orderId的值转成字串符,转成json字串后,再处理字符串,将orderId值两头的’'去掉,问题得到解决。
请求接口的JS代码实现:
/**
* 发送请求到对方接口
* @param {Object} dataJSON 提交的JSON数据
*/
const request = async (dataJSON) => {
try {
let partnerId = Env.get('PARTNERID');
let clientId = Env.get('CLIENTID');
let clientSecret = Env.get('CLIENTSECRET');
let noticeUrl = Env.get('CONSUME_NOTICE');//请求地址
//格式化签名日期(Wed, 02 Nov 2022 00:49:01 GMT)
let curDateStr = moment(new Date()).subtract(8,'hours').toString();
let tmStr = curDateStr.substring(0,curDateStr.indexOf('+'));
tmStr = tmStr.split(' ');
let sortDateStr = tmStr[0] + ', '+ tmStr[2] + ' ' + tmStr[1] + ' ' + tmStr[3] + ' ' + tmStr[4] + ' ' + tmStr[5];
//格式化验签请求地址
let signUrl = noticeUrl.substring(noticeUrl.indexOf('com/')+3);
let stringToSign = "POST "+signUrl+"\n" + sortDateStr;
console.log('Meituan stringToSign:', stringToSign);
const currSign = genSign(stringToSign,clientSecret);
let auth = "MWS " + clientId + ":" + currSign;
// 设置请求头数据
const config = {
url: signUrl,
method: 'POST',
headers: {
'PartnerId': partnerId,
'Authorization': auth,
'Date': sortDateStr,
'Content-Type': 'application/json;charset=UTF-8'
},
};
//去掉orderId值两头的单引号.
let reqStr = dealResponseOrderId(JSON.stringify(dataJSON));
console.log('reqStr:', reqStr);
const response = await Axios.post(noticeUrl, reqStr,config);
const data = response.data;
console.log(response.data);
if (data.code == 200) {
return {
success: true,
data: data,
};
} else {
return {
success: false,
message: data.describe
}
}
} catch (error) {
console.error(error);
return {
success: false
}
}
}
去掉返回值两边的单引号,写法有点粗糙,不喜勿喷~
/**
* 处理返回orderId(去掉返回值左右两边的字符串标识"").
* @param {Object} obj
*/
const dealResponseOrderId = (responseStr) => {
if (responseStr.indexOf('"orderId"') == -1) {
return responseStr;
}
let tmpStrs = responseStr.split('"orderId":"');
let resultStr = tmpStrs[1].substring(0,tmpStrs[1].indexOf('"'));
let result = tmpStrs[0]+'"orderId":'+resultStr+tmpStrs[1].substring(resultStr.length+1);
return result;
}