node配置微信小程序解密消息以及推送消息
上一篇文章介绍过 微信小程序配置消息推送,没有看过的可以先去查看一下,这里就直接去把那个客服消息接口去解密那个消息了。
在这里我选择的还是json格式的加密。

也就是给小程序客服消息发送的消息都会被微信转发到这里配置的地址和接口上面。
在页面中使用客服消息也就是如下这个效果,是需要用到微信提供的button标签上面的open-type的

点击进入客服消息也就是如下这个效果。

然后你发送的消息就会被转发到上面你配置的那个服务器的端口和那个接口上面,也就是例子中的

只不过配置确认的时候的接口是get请求方式,而微信转发消息到这里的接口这里是post请求方式。
在聊天窗口中发送消息,微信就会把加密后的消息转发到我们的接口 也就是 /checkPushMsg 上面,post请求方式。
在node中的代码接收,看看微信给我们转发了什么东西呢
// 配置前后端的推送消息
router.get('/checkPushMsg', wx_msg.check_push); // 那个函数就是如下的处理
exports.handle_customer_sevice = (req, res) => {
console.log('接收到了消息,请求体中');
console.log(req.body);
console.log('接收到了消息,请求url中');
console.log(req.query);
}
我们来查看一下发送过来的什么,我再用文档来比对一下哈。
现在我在手机上面那个页面里面发送一条消息,任意内容。
这里服务器的图片太小了,可以 按住 ctrl + 鼠标滚轮把这里放大看一下,我相信你肯定知道的。

请求url中的内容如下

请求体中的内容一个是发送者的 openid,另外一个加密的就是消息内容,它的构成是由 16个字节的随机字符串,4个字节的消息长度,发送的消息,appId由基于AES加解密算法加密而成的。
这里咱们先不着急解密发送的内容,我们要在解密之前先判断一下是不是微信发送过来的呢,如果不是你在这里解密半天然后发出去那不就难受了。
上面的图片中也详细的介绍了如何去判断是不是微信发送过来的消息。
我什么也不想解释了,直接上代码啦。
exports.handle_customer_sevice = (req, res) => {
console.log('接收到了消息,请求体中');
console.log(req.body);
console.log('接收到了消息,请求url中');
console.log(req.query);
let signature = req.query.signature,
timestamp = req.query.timestamp,
nonce = req.query.nonce,
openid = req.query.openid,
encrypt_type = req.query.encrypt_type,
msg_signature = req.query.msg_signature,
msg_encrypt = req.body.Encrypt; // 密文体
// 开发者计算签名
let devMsgSignature = sha1(pushToken, timestamp, nonce, msg_encrypt); // 这里的pushToken是 上面那个 配置消息推送 里面设置的Token令牌
if(devMsgSignature == msg_signature){
console.log('验证成功,是从微信服务器转发过来的消息');
res.send('success');
}else{
console.log('error');
res.send('error');
}
};
上面的那个sha1函数是这样的
/*
@explain sh1加密
@version 1.0.1 @author : Z
@data : 2019-2-13 @params : a,b,c……
@return : String 加密完成后的字符串
*/
exports.sha1 = function (...arr) {
return crypto.createHash('sha1').update(arr.sort().join('')).digest('hex');
};
上面就可以验证出来如果那个加密的东西确实是那样的就可以验证出来消息确实是由微信发送过来的。
然后就要开始解密了,这里我遇到了好多坑,说实话我也不知道下面的代码是谁第一个写出来的,因为官网上面根本就没有Node.js的代码,所以我也是看到了加密消息的构成部分,然后使用下面封装的函数解密。
/*
@explain: 微信的消息密文解密方法
@version 1.0.1
修复部分消息解析失败的情况
@author: Z
@data :2019-02-14
@params:
obj.AESKey:解密的aesKey值 这里的key就是配置消息推送的那部分
obj.text: 需要解密的密文
obj.corpid: 企业的id / 微信小程序的appid @return
obj.noncestr 随机数
obj.msg_len 微信密文的len
obj.msg 解密后的明文
*/ exports.decrypt = function (obj) {
let aesKey = Buffer.from(obj.AESKey + '=', 'base64');
const cipherEncoding = 'base64';
const clearEncoding = 'utf8';
const cipher = crypto.createDecipheriv('aes-256-cbc',aesKey,aesKey.slice(0, 16));
cipher.setAutoPadding(false); // 是否取消自动填充 不取消
let this_text = cipher.update(obj.text, cipherEncoding, clearEncoding) + cipher.final(clearEncoding);
/*
密文的构成
Base64_Encode(AES_Encrypt[random(16B) + msg_len(4B) + msg + $appId])
但是由于部分消息是不满足那个 32 位的,所以导致上面那个 cipher.final() 函数报错,所以修改为了自动填充,所以 appId后面还跟着一些字符
就无法正常解析了,所以就不返回 corpid 了,然后返回我们想要的东西。
*/
return {
noncestr:this_text.substring(0,16),
msg_len:this_text.substring(16,20),
msg:this_text.substring(20,this_text.lastIndexOf("}")+1)
}
};
其中的坑就是我遇到了那个 cipher.setAutoPadding(false) 这里填充的问题,但是有的消息是可以解密出来的,但是有的消息是不可以解密出来的,会报错,所以我就让所有的消息都填充了。
let this_tex = cipher.update(obj.text, cipherEncoding, clearEncoding) + cipher.final(clearEncoding);
解密消息这里的问题是,这是一个加法,前面的那个更新函数会改变 cipher的值,然后导致后面的那个值发生改变,当时找这个错误出现了很多问题。这个问题就是当字体的内容的长度不是32个字节还是什么的倍数的时候,这个函数会报一个500的错误码,然后不知道是哪里的问题,所以我就取消自动填充设置为了false,我就让它一直填充,然后处理那个消息,最后那个明文我再把最后的一个 } 后面截取掉。就可以展示出来了,但是这个里面就无法获取到小程序 appId 了,但是这又有什么必要呢?你后台肯定是知道appId的。
我把消息处理的完整代码发出来。
/*
消息体验证和解密
客服接收到的消息
handle_customer_sevice */ exports.handle_customer_sevice = (req, res) => {
console.log('接收到了消息,请求体中');
console.log(req.body);
console.log('接收到了消息,请求url中');
console.log(req.query);
let signature = req.query.signature,
timestamp = req.query.timestamp,
nonce = req.query.nonce,
openid = req.query.openid,
encrypt_type = req.query.encrypt_type,
msg_signature = req.query.msg_signature,
msg_encrypt = req.body.Encrypt; // 密文体 // 开发者计算签名
let devMsgSignature = sha1(pushToken, timestamp, nonce, msg_encrypt); if(devMsgSignature == msg_signature){
console.log('验证成功,是从微信服务器转发过来的消息'); let returnObj = decrypt({
AESKey: config.server.EncodingAESKey,
text: msg_encrypt,
corpid: config.app.appId
});
console.log('解密后的消息');
console.log(returnObj);
console.log('解密后的消息内容');
const decryptMessage = JSON.parse(returnObj.msg);
console.log(decryptMessage); /*
详细参数请查看官网 消息 https://developers.weixin.qq.com/miniprogram/dev/api/sendCustomerMessage.html
@params
access_token 调用接口凭证
touser 用户的openid
msgtype 消息类型
*/ if(JSON.parse(returnObj.msg).Content == '值班'){
axios.post(config.url.ip + config.url.P_CustomSend + '?access_token='+config.access_token, {
touser: decryptMessage.FromUserName,
msgtype: "text",
text: {
content: "发送消息"
}
})
.then(res => {
console.log('消息接口发送成功'); console.log(res.data);
if(res.data.errcode == 0){
console.log('消息发送成功');
}else if(res.data.errcode == 40001){
console.log('access_token过期');
}else{
console.log('其他错误信息')
}
console.log(res.data);
})
.catch(err => {
console.log('错误消息');
console.log(err);
})
}
res.send('success');
}else{
console.log('error');
res.send('error');
}
};
上面用到的两个函数 一个 sha1,另外一个就是 解密函数。
现在发送一下消息,看一看服务器上面的处理过程。

如此是可以解密出来那个消息的内容的,然后我设置了一个发送值班的话会给我发送一个消息。

如此 就大功告成了。
看了网上的许多文章大多都是Java,php的代码,很少有Node的代码,而且看了之后也不知道能不能弄出来,如果你遇到这个问题, 仔细看了我的文章之后,还有地方不知道,欢迎打扰我,告诉我哪里不清楚,我也会和你一起把你的问题解决掉。
如果解决了你的问题我会非常高兴的,其实上面的文章中我也感觉到了有一些地方描述的不是那么清晰,比如说消息加密的那一块,说实话,我也不是那么了解他的加密,只是微信 这里是有讲述的 点击查看
它的加密我会在最近几天研究一下,把他的加密的细节也给发出来,下一篇文章你可以查看到它的加密。
如果解决了你的问题我真的会非常高兴,因为我开发了这么久感觉开发出来的东西都没有去影响一些人,甚至我想先给自己做一些程序,并且我已经开始着手去做了,先去方便一下自己再去做一些去对一些人有好处的影响的东西。
node配置微信小程序解密消息以及推送消息的更多相关文章
- java微信小程序解密AES/CBC/PKCS7Padding
摘要:微信小程序解密建议使用1.6及以上的环境使用maven下载jar包org.bouncycastlebcprov-jdk15on1.55加密类代码importorg.bouncycastle.jc ...
- node.js微信小程序配置消息推送
在开发微信小程序时,有一个消息推送,它的解释是这样的. 消息推送具体的内容是下面的这个网址 https://developers.weixin.qq.com/miniprogram/dev/fra ...
- C# .net 填充无效,无法被移除 微信小程序解密失败的解决办法
微信小程序获取用户信息诸如unionId的时候需要解密,如果遇到偶然的解密失败(填充无效,无法被移除),原因很有可能是session_key错误, 也是就你用作解密的session_key并不是微信用 ...
- 微信小程序-登陆、支付、模板消息
wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要 ...
- 微信小程序解密得到unoinid和手机号 (开放数据的校验和解密 获取手机号)
实际测试 两种方法都可以: 第一种方法: public static string DecodeUserInfo(string encryptedData, string iv, string cod ...
- WebStorm 配置微信小程序开发 用html样式打开wxml 用css样式打开wxss 配置微信小程序提醒
1.点开preferences 2.搜索找到“File Types” 3.找到"HTML",点击“+”按钮,添加“*.wxml”然后“apply” 4.和3一样,再找到 ‘casc ...
- 微信小程序解密
获取OpenId和SessionKey private string GetOpenIdAndSessionKeyString(string code) { string wxUrl = " ...
- 微信小程序客服消息使用指南
客服消息使用指南 为丰富小程序的服务能力,提高服务质量,微信为小程序提供客服消息能力,以便小程序用户可以方便快捷地与小程序服务提供方进行沟通. 功能介绍 用户可使用小程序客服消息功能,与小程序的客服人 ...
- 微信小程序客服消息使用
客服消息使用 为丰富小程序的服务能力,提高服务质量,微信为小程序提供客服消息能力,以便小程序用户可以方便快捷地与小程序服务提供方进行沟通. xiaokefu.com.cn 功能介绍 用户可使用小程序客 ...
随机推荐
- Scrapy爬取Ajax(异步加载)网页实例——简书付费连载
这两天学习了Scrapy爬虫框架的基本使用,练习的例子爬取的都是传统的直接加载完网页的内容,就想试试爬取用Ajax技术加载的网页. 这里以简书里的优选连载网页为例分享一下我的爬取过程. 网址为: ht ...
- netcore编程之后面对不习惯的xshell黑屏部署,是时候使用jenkins自动化发布工具了
在很久之前net还只能在windows上部署的时候,或许很多创业公司的朋友发布项目还都是人肉部署,反正windows都是可视化的界面,拖拖拉拉,开开关关还不 是特别麻烦...现如今你的项目需要在li ...
- 实时语音趣味变声,大叔变声“妙音娘子”Get一下
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云 发表于云+社区专栏 游戏社交化是近年来游戏行业发展的重要趋势,如何提高游戏的社交属性已成为各大游戏厂商游戏策划的重要组成部 ...
- react-native 金币彩带雨下落动画
日常项目中,经常遇到一些表情雨/金币雨/彩带雨 等下落的动画,之前做android原生的时候,写过类似的效果,主要通过自定义view 在onDraw里绘制下落的过程,具体可以看下我的这篇github地 ...
- Android 上传图片到服务器二--------调用相机7.0以上权限问题
[目录] (一)上传图片到服务器一 ---------------------------------Android代码 (二)上传图片到服务器二--------------------------- ...
- Linux基本操作——文件相关
一.前言 无论是IC工程师.FPGA工程师还是嵌入式软件工程师,都或多或少会接触到Linux操作系统.有很多EDA工具只有Linux版本,因此掌握基本的操作和常用命令十分必要.Linux中的数据均以文 ...
- windows手动去重 通配符
在下载文件时,如果遇到重复文件,windows的默认做法时 文件名(数字) 这样的方式重命名的. 那么我们在排除重复文件时,可以使用 windows文件浏览器提供的查找功能, 用通配符 ~=& ...
- 判断JS数据类型的四种方法
在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined.N ...
- hadoop 笔记(hive)
//**********************************//安装配置1. 修改配置文件 1.1 在conf文件夹下 touch hive-site.xml <configurat ...
- v-cloak的用法和注意事项
v-cloak是前端框架vue.js中的一个方法,作用是为了防止在页面加载时先出现变量名闪烁的情况,造成不好的用户体验, 例如:{{ v.name}} (闪一下)=> 张三 用法:html中:& ...