const result = await rp({ url: url, method: 'POST', // json: true, // 自动将请求体转换为JSON格式 headers: { 'Content-type': 'application/json;charset=utf-8', 'Wechatmp-Appid': 'wx5c396ba640e68749', 'Wechatmp-TimeStamp': newReq.req_ts, 'Wechatmp-Signature': signature }, body: newReq.req_data // 将加密数据作为请求体 }); return result.body; 以上是我在云函数中使用引入request库发起的请求,对于加密和签名后的api请求要把json:true去除 还有一个问题 const new_req = { req_ts: local_ts, req_data: JSON.stringify(req_data) } return new_req 官方代码中加密后return的new_req是带时间戳的,方便签名方法直接传参使用,我们具体发送请求的时候一定要用new_req.req_data, 当上述 两个问题加在一起时 会导致 40234 , invalid signature 如果你的签名和加密参数没问题不妨看下有没有像我一样粗心 😊
小程序即时配送加密签名40234?为什么/(ㄒoㄒ)/~~,官方大大// 云函数入口文件 const cloud = require('wx-server-sdk') const request = require('request'); // 引入 request 库 const crypto = require('crypto'); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境 // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext() try { // 获取access_token和请求参 const { access_token, queryParams } = event // 获取加密请求数据 const ctxEco = getEcoCtx('https://api.weixin.qq.com/cgi-bin/express/intracity/querystore') // 开发者本地信息 console.log("ctxEco", ctxEco) const req = queryParams // 请求数据 console.log("req", req) const newReq = getNewReq(ctxEco, req) // 生成加密请求数据 console.log("newReq", newReq) const ctxSign = getSignCtx('https://api.weixin.qq.com/cgi-bin/express/intracity/querystore') console.log("ctxSign", ctxSign) const signature = getSignature(ctxSign, newReq) // 获取签名 console.log("signature", signature) // 执行查询门店接口请求 const response = await queryStore(access_token, signature, newReq) console.log("response", response) return response; } catch (error) { console.error('请求错误:', error); return error; } } // 查询门店信息的POST请求 async function queryStore(access_token, signature, newReq) { const url = `https://api.weixin.qq.com/cgi-bin/express/intracity/querystore?access_token=${access_token}`; const rp = options => new Promise((resolve, reject) => { request(options, (error, response, body) => { if (error) { reject(error); } resolve(response); }); }); const result = await rp({ url: url, method: 'POST', json: true, // 自动将请求体转换为JSON格式 headers: { 'Wechatmp-Appid': 'appid', 'Wechatmp-TimeStamp': newReq.req_ts, 'Wechatmp-Signature': signature }, body: newReq // 将加密数据作为请求体 }); return result.body; } // 获取开发者本地信息 function getSignCtx(url) { let ctx = { local_private_key: "-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----", local_sn: "sn", local_appid: "appid", url_path: url } return ctx } // 仅做演示,敏感信息请勿硬编码 function getEcoCtx(url) { let ctx = { local_sym_key: "sym_key", local_sym_sn: "sym_sn", local_appid: "appid", url_path: url } return ctx } // 获取加密后的请求数据 function getNewReq(ctx, req) { const { local_sym_key, local_sym_sn, local_appid, url_path } = ctx // 开发者本地信息 const local_ts = Math.floor(Date.now() / 1000) //加密签名使用的统一时间戳 const nonce = crypto.randomBytes(16).toString('base64').replace(/=/g, '') const reqex = { _n: nonce, _appid: local_appid, _timestamp: local_ts } const real_req = Object.assign({}, reqex, req) // 生成并添加安全校验字段 const plaintext = JSON.stringify(real_req) const aad = `${url_path}|${local_appid}|${local_ts}|${local_sym_sn}` const real_key = Buffer.from(local_sym_key, "base64") const real_iv = crypto.randomBytes(12) const real_aad = Buffer.from(aad, "utf-8") const real_plaintext = Buffer.from(plaintext, "utf-8") const cipher = crypto.createCipheriv("aes-256-gcm", real_key, real_iv) cipher.setAAD(real_aad) let cipher_update = cipher.update(real_plaintext) let cipher_final = cipher.final() const real_ciphertext = Buffer.concat([cipher_update, cipher_final]) const real_authTag = cipher.getAuthTag() const iv = real_iv.toString("base64") const data = real_ciphertext.toString("base64") const authtag = real_authTag.toString("base64") const req_data = { iv, data, authtag, } const new_req = { req_ts: local_ts, req_data: JSON.stringify(req_data) } return new_req } // 获取签名 function getSignature(ctx, req) { const { local_private_key, local_sn, local_appid, url_path } = ctx // 开发者本地信息 const { req_ts, req_data } = req // 待请求API数据 const payload = `${url_path}\n${local_appid}\n${req_ts}\n${req_data}` const data_buffer = Buffer.from(payload, 'utf-8') const key_obj = { key: local_private_key, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST // salt长度,需与SHA256结果长度(32)一致 } const sig_buffer = ss_buffer = crypto.sign( 'RSA-SHA256', data_buffer, key_obj ) const sig = sig_buffer.toString('base64') return sig }
11-18