版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41196185/article/details/82744288
为了梳理代码,我单独给微信的接口进行了一些封装。这是前面认证接口的内容。
封装接口用到了request
npm install --save request
封装的 js 结构大致是这样的
var request = require('request');
var crypto = require('crypto');
function WeChat(config) {
this.config = config
this.accessToken = null
this.getAccessTokenTimer = null
}
WeChat.prototype.Authenticate = function(req, res) {
//1.获取微信服务器Get请求的参数 signature、timestamp、nonce、echostr
var signature = req.query.signature,//微信加密签名
timestamp = req.query.timestamp,//时间戳
nonce = req.query.nonce,//随机数
echostr = req.query.echostr;//随机字符串
//2.将token、timestamp、nonce三个参数进行字典序排序
var array = [this.config.token,timestamp,nonce];
array.sort();
//3.将三个参数字符串拼接成一个字符串进行sha1加密
var tempStr = array.join('');
const hashCode = crypto.createHash('sha1'); //创建加密类型
var resultCode = hashCode.update(tempStr,'utf8').digest('hex'); //对传入的字符串进行加密
//4.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if(resultCode === signature){
res.send(echostr);
}else{
res.send('mismatch');
}
}
module.exports.WeChat = WeChat;
扯多了,回到正题access_token
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
因此,我继续封装了GetAccessToken方法。
WeChat.prototype.GetAccessToken = function() {
var self = this
let option = {
url: 'https://api.weixin.qq.com/cgi-bin/token',
qs: {
grant_type: 'client_credential',
appid: this.config.App_Id,
secret: this.config.App_Secret
},
method: 'GET',
headers: {
"content-type": "application/json"
}
}
return new Promise((resolve, reject) => {
request(option, function(error, response, body) {
console.log(error, body)
var data = JSON.parse(body)
if (error) {
reject(error)
} else {
switch(data.errcode) {
case 45009:
console.log('token调用上限')
reject(data)
break
case 0:
self.accessToken = {
access_token: data.access_token,
expires_in: data.expires_in
}
console.log('当前access_token', JSON.stringify(self.accessToken))
// 定时重新获取access_token
clearTimeout(this.getAccessTokenTimer)
this.getAccessTokenTimer = setTimeout(() => {
self.GetAccessToken()
}, (data.expires_in - 60) * 1000 || 60000)
resolve(data)
break
}
}
})
})
}
并在express服务启动的时候调用GetAccessToken,调用成功后会依据 expires_in 起定时器重新获取。
var wechat = new WeChat(config)
wechat.GetAccessToken().then(success => {
console.log('初始化获取accessToken成功')
}, failure => {
console.log('初始化获取accessToken失败')
})
2018.10.17
考虑到每次重启服务器都会调用GetAccessToken,会导致频繁调用。因此想到一个修改方法,将accessToken作为属性存在wechat对象中的同时,还将其写入到本地文件token.json中。这样服务器重启时,就可以先读取token.json文件中的access_token及expires_in,先判断是否过期,如果过期了,则直接进行access_token更新操作,否则计算出过期时间,用定时器控制在过期时间时进行access_token更新操作。