18910140161

node.js解析微信消息推送xml格式加密的消息

顺晟科技

2021-06-16 10:59:24

586

之前写了一个解密json格式加密。我认为xml和json很相似。那是上周五。我同事也在微信微信官方账号里做消息推送解密,发现好像只能用xml加密格式发送到服务器。去年还做了企业微信的消息推送解密。真的,虽然感觉差不多,但是如果用同样的代码,三个完全不能复用,但是你做了一个之后,再做别的,就明白他的原理了。我正在github上逐节点完善微信各种API的配置和使用。所有的源代码都在https://github.com/zzz111111/wx_app的地址里,并且使用了express框架。

事实上,xml格式的解密类似于json格式,只是express框架的一些问题影响了我们。在使用body-parser中间件后,json格式的数据将被添加到req.body中,但是在xml格式中,我们一般不使用其他中间件将xml格式的数据添加到req.body中.在这里,我使用express-xml-bodyparser中间件来解析出xml,或者我可以不使用这些中间件,直接使用本机代码来获取数据。

使用中间件的代码。

1 const XML parser=require(' express-XML-body parser ');

2

3 app . use(xmlparser());/*添加用于解析微信的xml格式文件*/

6 router.post('/your address ',(req,res)={

7 console.log('在请求url中收到');

8 console . log(req . query);

9 console.log('收到请求,在请求正文中');

10 console . log(req . body);

11 });

不用中间件就可以得到。之所以写这个,是因为同事用koa2框架,找不到解析xml格式的中间件,所以后来在网上找了一些资料,自己写了一个。

刚才,在测试过程中,我找到了所请求的内容在本机req对象上的位置。我也是天才。Koa2框架。

1 router.post('/xml ',async ctx={

2 console.log('请求xml接口');

4 console . log(CTX . req . readablestate . buffer);

5 console.log('其他内容-head ');

6 var buf 1=CTX . req . _ readablestate . buffer . head . data;

7 console . log(buf 1);

8控制台. log(新缓冲区(buf1)。toString());

9 console.log('其他内容-tail ');

10 var buf 2=CTX . req . _ readablestate . buffer . tail . data;

11 console . log(buf 2);

12 console.log(新缓冲区(buf2)。toString());

13 ctx.body=' xml

14 })

Buffer对象转换的两个对象都是xml格式的对象。

这里,xml格式的内容仍然是一个字符串,所以我们首先以正常的方式获取请求体中的内容,然后解析它。

以上纯属扯淡。一般在我们属性的名字前面加一个_(也就是下划线),表示这个东西不想被外界访问,所以由正常人操作。正常得到。

1路由器. post('/xmlTest ',async ctx={

2 console.log('请求xml接口');

3 var数据=' ';

4 ctx.req.on('data ',(chunk)={

5 data=chunk

6 });

7 ctx.req.on('end ',()={

8 console.log('数据传输结束');

9 console.log(数据);

10 });

11 ctx.body=' xml

12 });

这是我向他要的。

只有这样才能正常得到请求的xml格式,然后我们用xml2js模块解析,转换成json格式对象。

npm i -S xml2js

xml到json和json到xml的方法

1 const xml={

2 xmlToJson(str){

3返回新承诺((解决,拒绝)={

4 const ParseString=xml2js . ParseString

5 parseString(str,(err,result)={

6 if (err) {

7拒绝(错误)

8 }其他{

9解决(结果)

10 }

11 })

12 })

13 },

14 JSontXMl(){

15 const builder=new xml2js。建设者()

16 return builder . BuildObject(obj)

17 }

18

19 }

我们可以使用koa2,洋葱模型,在前面的方法中解析xml文件,并把它放在ctx.req.body之上来访问它。

1路由器. post('/xml2 ',async (ctx,next)={

2 if(CTX . method==' POST ' CTX . is(' text/XML '){

3让承诺=新承诺(功能(解决,拒绝){

4让buf=' '

5 ctx.req.setEncoding('utf8 ')

6 ctx.req.on('data ',(chunk)={

7 console.log('接收数据');

9 console . log(chunk);

10 buf=chunk

11

12 })

13 ctx.req.on('end ',()={

14 xml.xmlToJson(buf)

15 .然后(解决)

16 .捕捉(拒绝)

17 })

18 })

19

20等待承诺

21 ctx.req.body=结果

22 })

23 .catch((e)={

24 e.status=400

25 })

26

27下一个()

28 }其他{

29等待下一个()

30 }

31 },异步ctx={

32 console . log(CTX . req . body);

33

34 console . log(CTX . req . body . XML . TouseName[0])

35 ctx.body='第二次返回信息';

36 });

以上可以解析,xml格式转换成json对象。

本文的主题是解析微信推送的xml消息。不能跑题。以上都是铺垫和基础。当时,因为我们无法获得xml数据,我们搜索了很长时间。express将直接安装上面提到的中间件。koa2可以自己写,也可以得到。

八卦就不多说了,拿到手后和json格式没什么区别,可以看看json格式的解析。

因为我用的是express框架,把方法列表分开,所以可以把代码发出去,去我的github上看看详细情况,地址也给了。

1 /**

2 *这里的方法解析微信消息加密的XML格式

3 *

4 *流程介绍如下

5 * 1.首先获取消息网址中的字符串,然后获取消息正文中的秘密样式

6 * 2.验证微信对URL和密式提供的加密方式是否等于消息体签名,验证消息是否由微信转发

7 * 3.步骤2验证成功后,对微信消息进行解密,解密功能在工具功能中

8 *

9 *网址中的内容

10 *

11 * @params {String}签名字符串

12 * @params {String}时间戳时间戳

13 * @params {String}随机数随机字符串

14 * @params {String} encrypt_type加密类型(aes)

15 * @params {String} openid

16 * @ params { string } msg _ signature消息正文签名。用于验证消息正文的正确性

17 *

18 *请求正文中的内容-解析后

用户名小程序的原始id的19 * @ params {string}

20 * @params {String}加密加密的消息字符串

21 *

22 */

23 exports . handlecustomerserverxML=(req,res)={

24 console.log('在请求url中收到');

25 console . log(req . query);

26 console.log('收到请求,在请求正文中');

27 console . log(req . body);

28 const {signature,timestamp,nonce,encrypt_type,openid,msg _ signature }=req.query

29 const msg _ encrypt=req . body . XML . encrypt[0];

30

31 //验证消息的正确性

32 const dev _ msg _ signature=sha1(config . PushToken,timestamp,nonce,msg _ encrypt);

33 if(dev _ msg _ signature==msg _ signature){

34 //签名消息正确,从微信服务器解密

35 const LastData=utils . DecryptXMl({

36 AES key : config . server . encoding AES key,

37文本:消息_加密,

38 corpid: config.app.appId

39 });

40 console . log(' msg函数中接收的数据内容');

41

42 console . log(LastData);

43 console.log('收到的消息是-' last data . msg . XML . content[0]);

四十四

45 var msgArr={

46 '新年快乐' : '祝你新年快乐',

47 '值班' : '我今天不上班,你值得你m ',

48' Hello' :' Hello ',

49 '什么' : '你在说什么'

50 };

51 var replyMsg=MsGarr[LastData . msg . XML . content[0]];

52 if(replyMsg){

53 ZY.msg.textMsg(openid,openid,replyMsg)

54 .然后(res={

55控制台. log('消息发送成功!');

56 console . log(RES);

57 })

58 .catch(err={

59 console.log('消息发送失败');

60 console . log(err);

61 })

62 }else{

63 ZY.msg.textMsg(openid,openid,'看你在说什么?')

64 .然后(res={

65控制台. log('消息发送成功!');

66 console . log(RES);

67 })

68 .catch(err={

69 console.log('消息发送失败');

70控制台。log(err);

71 })

72 }

73 res.send('成功');

74 }其他{

75 console.log('非微信服务器试图发送消息给我!');

76 res.send('你在玩啥呢?');

77 }

78 }

sha1方法

1 /*

2 @解释sh1加密

3 @ 1 .0 .一版

5 @作者: Z

6 @data : 2019-2-13

8 @params {String,String.} a、b、c……

9 @return {String}加密完成后的字符串

10 */

11出口. sha1=函数(.arr) {

12返回crypto.createHash('sha1 ').update(arr.sort().join(').摘要(' hex ');

13 };

只针对于可扩展标记语言格式的解析方法。

1 /**

2 * 解析微信上传消息此方法只解析可扩展置标语言格式

3 * @ 1 .0 .0版

4 * @数据2019-3-21

5 *

6 * @参数{对象}

7 * obj .AESKey:解密的aesKey值

8 * obj.text:需要解密的密文

9 * obj.corpid:企业的id /微信小程序的应用编号

10 *

11 * @返回{对象}

12 * obj.noncestr随机数

13 * obj.msg_len微信密文的低输入联网(低入门网络的缩写)

14 * obj.msg解密后的明文数据格式

15 * obj.corpid错乱的应用编号尾部填充了些东西,可以舍弃,因为我们知道自己的应用编号是多少,不需要这里告诉我们

16 *

17 */

18出口。decryptXMl=函数(obj){

19让aesKey=Buffer.from(obj .AESKey '=',' base64 ');

20 const CircuIt编码=' base64

21 const clearEncoding=' utf8

22常量密码=加密。createdecidepheriv(' AES-256-CBC ',aesKey,aesKey.slice(0,16));

23密码。setautopadding(false);//是否取消自动填充不取消

24让this _ text=密码。更新(obj。文本、密码编码、明文编码)。final(clearEncoding);

25让xmlText=

26 xml2js。ParseString(this _ text。substring(20,this _ text。'(1)的最后一个索引,函数(错误,结果){

27 if(err)throw err;

28 xmlText=结果;

29 });

30返回{

31 noncrest : thi _ text。子串(0,16),

32 msg _ len : this _ text。子串(16,20),

33 msg:xmlText,

34 corpid : this _ text。substring(this _ text。'(1)的最后一个索引

35 }

36 }

放到服务器上面的打印是这样的。

那些看不到的信息,可以在加密的函数中打印看到到底返回来什么。

回复的消息图。

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航