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)
})
})
}
内容版权声明:除非注明,否则皆为本站原创文章。
