上篇把nodejs代码全部写在了app.js里面,现在把代码封装一下。
--------开始:抽离加密验证中间件-------------
第一步:在wechat目录下建立wechat/g.js,作为一个中间件

第二步:在g.js文件中写验证加密中间件
var sha1 = require('sha1')
module.exports = function(opts){
return async (ctx) =>{
console.log('aa',ctx.query)
var token =opts.token;
var signature = ctx.request.query.signature;
var nonce = ctx.request.query.nonce;
var timestamp = ctx.request.query.timestamp;
var echostr = ctx.request.query.echostr;
var str = [token,timestamp,nonce].sort().join('')
var sha = sha1(str)
console.log('sha',sha)
console.log('signature',signature)
if(sha === signature){
ctx.body = echostr + '';
}else{
ctx.body = 'err'
}
}
}
第三步:在app.js中引入中间件g.js
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-08-24 16:30:18
* @LastEditTime: 2019-08-24 18:41:12
* @LastEditors: Please set LastEditors
*/
var Koa = require('koa')
var wechat = require('./wechat/g')
var config = {
wechat:{
appID:'你的appid',
appSecret:'你的appsecret',
token:'你的token'
}
}
var app = new Koa()
app.use(wechat(config.wechat))
app.listen(1234)
console.log('listen 1234')
-------结束:以上抽离了加密验证中间件------------
-------开始:access_token------------
access_token
- 每2个小时自动失效,需要重新获取。让系统每个2个小时启动去刷新,保持始终最新。
- 新建config和libs目录,此时结构是这样

- wechat/g.js
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-08-24 18:37:34
* @LastEditTime: 2019-08-26 10:14:16
* @LastEditors: Please set LastEditors
*/
var sha1 = require('sha1')
var Promise = require('bluebird')
var request = Promise.promisify(require('request'))
var prefix = 'https://api.weixin.qq.com/cgi-bin/'
var api = {
accessToken:prefix+'token?grant_type=client_credential'
}
function Wechat(opts){
var that = this;
this.appID = opts.appID;
this.appSecret = opts.appSecret;
this.getAccessToken = opts.getAccessToken;
this.saveAccessToken = opts.saveAccessToken;
this.getAccessToken()
.then(function(data){
try{
data = JSON.parse(data)
}catch(e){
return that.updateAccessToken()
}
if(that.isValidAccessToken(data)){
Promise.resolve(data)
}else{
return that.updateAccessToken()
}
})
.then(function(data){
console.log('data',data)
that.access_token = data.access_token;
that.expires_in = data.expires_in;
that.saveAccessToken(data)
})
}
Wechat.prototype.isValidAccessToken = function(data){
if(!data || !data.access_token || !data.expires_in){
return false;
}
var access_token = data.access_token;
var expires_in = data.expires_in;
var now = (new Date().getTime())
if(now<expires_in){
return true;
}else{
return false;
}
}
Wechat.prototype.updateAccessToken = function(){
var appID = this.appID;
var appSecret = this.appSecret;
var url = api.accessToken + '&appid=' + appID + '&secret=' + appSecret
return new Promise(function(resolve,reject){
request({url:url,json:true}).then(function(response){
var data = response.body
var now = (new Date().getTime())
var expires_in = now + (data.expires_in - 20) * 1000
data.expires_in = expires_in
resolve(data)
})
})
}
module.exports = function(opts){
var wechat = new Wechat(opts)
return async (ctx) =>{
console.log('aa',ctx.query)
var token =opts.token;
var signature = ctx.request.query.signature;
var nonce = ctx.request.query.nonce;
var timestamp = ctx.request.query.timestamp;
var echostr = ctx.request.query.echostr;
var str = [token,timestamp,nonce].sort().join('')
var sha = sha1(str)
console.log('sha',sha)
console.log('signature',signature)
if(sha === signature){
ctx.body = echostr + '';
}else{
ctx.body = 'err'
}
}
}
- app.js
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-08-24 16:30:18
* @LastEditTime: 2019-08-26 10:11:55
* @LastEditors: Please set LastEditors
*/
var Koa = require('koa')
var path = require('path')
var wechat = require('./wechat/g')
var util = require('./libs/util')
var wechat_file = path.join(__dirname,'./config/wechat.txt')
var config = {
wechat:{
appID:'你的appid',
appSecret:'你的appsecret',
token:'你的token',
getAccessToken:function(){
return util.readFileAsync(wechat_file)
},
saveAccessToken:function(data){
data = JSON.stringify(data)
return util.writeFileAsync(wechat_file,data)
}
}
}
var app = new Koa()
app.use(wechat(config.wechat))
app.listen(1234)
console.log('listen 1234')
- libs/util.js
/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-08-26 09:33:56
* @LastEditTime: 2019-08-26 10:15:19
* @LastEditors: Please set LastEditors
*/
var fs = require('fs')
var Promise = require('bluebird')
exports.readFileAsync = function(fpath,encoding){
return new Promise(function(resolve,reject){
fs.readFile(fpath,encoding,function(err,content){
if(err){
reject(err)
}else{
resolve(content)
}
})
})
}
exports.writeFileAsync = function(fpath,content){
return new Promise(function(resolve,reject){
fs.writeFile(fpath,content,function(err){
if(err){
reject(err)
}else{
resolve()
}
})
})
}
-------结束:access_token------------
-------开始:自动回复------------
五个步骤
- 1.处理POST类型的控制逻辑,接受这个XML的数据包
- 2.解析这个数据包(获得数据包的消息类型或者是事件类型)
- 3.拼装我们定义好的消息
- 4.包装成xml的格式
- 5.在5s内返回回去
自动回复代码放到了 github