上一篇文章介绍过 微信小程序配置消息推送,没有看过的可以先去查看一下,这里就直接去把那个客服消息接口去解密那个消息了。

  在这里我选择的还是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配置微信小程序解密消息以及推送消息的更多相关文章

  1. java微信小程序解密AES/CBC/PKCS7Padding

    摘要:微信小程序解密建议使用1.6及以上的环境使用maven下载jar包org.bouncycastlebcprov-jdk15on1.55加密类代码importorg.bouncycastle.jc ...

  2. node.js微信小程序配置消息推送

    在开发微信小程序时,有一个消息推送,它的解释是这样的. 消息推送具体的内容是下面的这个网址   https://developers.weixin.qq.com/miniprogram/dev/fra ...

  3. C# .net 填充无效,无法被移除 微信小程序解密失败的解决办法

    微信小程序获取用户信息诸如unionId的时候需要解密,如果遇到偶然的解密失败(填充无效,无法被移除),原因很有可能是session_key错误, 也是就你用作解密的session_key并不是微信用 ...

  4. 微信小程序-登陆、支付、模板消息

    wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要 ...

  5. 微信小程序解密得到unoinid和手机号 (开放数据的校验和解密 获取手机号)

    实际测试 两种方法都可以: 第一种方法: public static string DecodeUserInfo(string encryptedData, string iv, string cod ...

  6. WebStorm 配置微信小程序开发 用html样式打开wxml 用css样式打开wxss 配置微信小程序提醒

    1.点开preferences 2.搜索找到“File Types” 3.找到"HTML",点击“+”按钮,添加“*.wxml”然后“apply” 4.和3一样,再找到 ‘casc ...

  7. 微信小程序解密

    获取OpenId和SessionKey private string GetOpenIdAndSessionKeyString(string code) { string wxUrl = " ...

  8. 微信小程序客服消息使用指南

    客服消息使用指南 为丰富小程序的服务能力,提高服务质量,微信为小程序提供客服消息能力,以便小程序用户可以方便快捷地与小程序服务提供方进行沟通. 功能介绍 用户可使用小程序客服消息功能,与小程序的客服人 ...

  9. 微信小程序客服消息使用

    客服消息使用 为丰富小程序的服务能力,提高服务质量,微信为小程序提供客服消息能力,以便小程序用户可以方便快捷地与小程序服务提供方进行沟通. xiaokefu.com.cn 功能介绍 用户可使用小程序客 ...

随机推荐

  1. 动态路由协议(RIP)

    虽然静态路由在某些时刻很有用,但是必须手工配置每条路由条目,对于大中型的网络或拓补经常发生变化的清空,配置和维护静态路由的工作量就变得非常繁重,而且不小心还容易出错,因此就需要一种不需要手工配置的路由 ...

  2. ArcGIS注册数据库问题分析

    本文是'猴妹'师妹授权给我来发表的,介绍都是师妹的研究成果,在此,非常感谢'猴妹'师妹. 用ArcGIS Server在发布地图服务时,注册数据库是很常见的,几年前就开始注册数据库,直到昨天,才有点顿 ...

  3. 使用FakeAPP进行AI换脸必看!!

    C盘生于容量小于5G的千万别用啊!!笔者本人因为C盘只剩了3G,根本用不上这个,最后会把大小为4G的core文件必须移植到C盘当中,俺的CUDA也白安装了,而且还不小心安装成CUDA8了,应该用9好么 ...

  4. ABP学习笔记总汇

    首先立下一个目标,未来一段时间开始学习ABP. 先立一个flag.之后会再次更新目录和文章连接 目录 1.ABP学习笔记(1)-使用mysql

  5. shell if条件判断中:双中括号与单中括号的区别

    电脑重装了系统,登录虚拟机的shell脚本需重写,在为编写的脚本命名时发现存在同名脚本,才想起来是连接公司服务器的登录脚本,不想写俩脚本,怕记混了,那就整合一下.代码如下: #!/bin/bash#z ...

  6. pandas的apply操作

    pandas的apply操作类似于Scala的udf一样方便,假设存在如下dataframe: id_part pred pred_class v_id 0 d [0.722817, 0.650064 ...

  7. 【机器学习】--xgboost从初识到应用

    一.前述 在 Kaggle 的很多比赛中,我们可以看到很多 winner 喜欢用 xgboost,而且获得非常好的表现,今天就来看看 xgboost 到底是什么以及如何应用.Gradient boos ...

  8. 网络协议 17 - HTTPDNS:私人定制的 DNS 服务

    [前五篇]系列文章传送门: 网络协议 12 - HTTP 协议:常用而不简单 网络协议 13 - HTTPS 协议:加密路上无尽头 网络协议 14 - 流媒体协议:要说爱你不容易 网络协议 15 - ...

  9. java~lombok里的Builder注解

    lombok注解在java进行编译时进行代码的构建,对于java对象的创建工作它可以更优雅,不需要写多余的重复的代码,这对于JAVA开发人员是很重要的,在出现lombok之后,对象的创建工作更提供Bu ...

  10. 基于python脚本,实现Unity全平台的自动打包

    转载请标明出处:http://www.cnblogs.com/zblade/ 0. 概述 本文主要针对项目中自动打包过程进行调研,实现用python脚本来打出win/android/ios三个平台下的 ...