Koa2微信公众号开发之消息管理(2)
这儿我们在只在GET中验证了签名值是否合法,实际上我们在POST中也应该验证签名。
将签名验证写成一个函数
function getSignature (timestamp, nonce, token) { let hash = crypto.createHash('sha1') const arr = [token, timestamp, nonce].sort() hash.update(arr.join('')) return hash.digest('hex') }
优化代码,再POST中也加入验证
... app.use(async ctx => { const { signature, timestamp, nonce, echostr } = ctx.query const TOKEN = config.wechat.token if (ctx.method === 'GET') { if (signature === getSignature(timestamp, nonce, TOKEN)) { return ctx.body = echostr } ctx.status = 401 ctx.body = 'Invalid signature' }else if (ctx.method === 'POST') { if (signature !== getSignature(timestamp, nonce, TOKEN)) { ctx.status = 401 return ctx.body = 'Invalid signature' } // TODO } }); ...
到这儿我们都没有开始实现接受XML数据包的功能,而是在修改之前的代码。这是为了演示在实际开发中的过程,写任何代码都不是一步到位的,好的代码都是改出来的。
2.3 接收公众号普通消息的XML数据包
现在开始进入本节的重点,接受XML数据包并转为JSON
$ npm install raw-body --save
... const getRawBody = require('raw-body') ... // TODO // 取原始数据 const xml = await getRawBody(ctx.req, { length: ctx.request.length, limit: '1mb', encoding: ctx.request.charset || 'utf-8' }); console.log(xml) return ctx.body = 'success' // 直接回复success,微信服务器不会对此作任何处理
给你的测试号发送文本消息,你可以在命令行看见打印出如下数据
<xml> <ToUserName><![CDATA[gh_9d2d49e7e006]]></ToUserName> <FromUserName><![CDATA[oBp2T0wK8lM4vIkmMTJfFpk6Owlo]]></FromUserName> <CreateTime>1516940059</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[JavaScript之禅]]></Content> <MsgId>6515207943908059832</MsgId> </xml>
恭喜,到此你已经可以接收到XML数据了。😯 但是我们还需要将XML转为JSON方便我们的使用,我们将用到xml2js这个包
$ npm install xml2js --save
我们需要写一个解析XML的异步函数,返回一个Promise对象
function parseXML(xml) { return new Promise((resolve, reject) => { xml2js.parseString(xml, { trim: true, explicitArray: false, ignoreAttrs: true }, function (err, result) { if (err) { return reject(err) } resolve(result.xml) }) }) }
内容版权声明:除非注明,否则皆为本站原创文章。