- 进入ngrok官网 (ngrok.com/),注册ngrok账号…
- 根据官网运行命令
./ngrok authtoken 1joIjHUJ2sQroatUKIWWhpKR94A_54HcKBHWJyzgTdiq5wDwZ./ngrok http 30003000是端口号 可以换成自己想要的端口号
运行成功如图
Forwarding,第一个是http协议对应的外网地址,第二个是https协议对应的外网地址。这样,凡是访问e45968c45c8b.ngrok.io的请求都将发送到localhost:3000。
-
微信公众号测试号配置
-
本地服务器配置 (koa2) 接口认证
router.get('/', async ctx => {
console.log(ctx.query);
const { signature, timestamp, nonce, echostr } = ctx.query
const token = 'wzm';
ctx.body = echostr;
})
- 微信公众号自动信息回复案例
const Koa = require('koa');
const app = new Koa();
let Router = require('koa-router');
let router = new Router();
const getRawBody = require('raw-body');
const crypto = require('crypto');
// 解析xml数据为json格式
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)
})
})
}
// 判断是否为微信服务器信息
function getSignature(timestamp, nonce, token) {
let hash = crypto.createHash('sha1')
const arr = [token, timestamp, nonce].sort()
hash.update(arr.join(''))
return hash.digest('hex')
}
app.use(async ctx => {
const { signature, timestamp, nonce, echostr } = ctx.query
const TOKEN = 'wzm';
console.log(ctx.method)
if (ctx.method === 'GET') {
if (signature === getSignature(timestamp, nonce, TOKEN)) {
const xml = await getRawBody(ctx.req, {
length: ctx.request.length,
limit: '1mb',
encoding: ctx.request.charset || 'utf-8'
});
console.log(xml)
const formatted = await parseXML(xml)
console.log(formatted)
}
} else if (ctx.method === 'POST') {
let data = ctx.request.body
if (signature === getSignature(timestamp, nonce, TOKEN)) {
console.log(data);
const formatted = await parseXML(data)
console.log(formatted)
// 回复微信公众号信息
ctx.type = 'application/xml';
return ctx.body = `<xml>
<ToUserName><![CDATA[${formatted.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${formatted.ToUserName}]]></FromUserName>
<CreateTime>${new Date().getTime()}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[这儿是JavaScript之禅]]></Content>
</xml>`
}
}
});
app.use(router.routes()).use(router.allowedMethods())