为了梳理代码,我单独给微信的接口进行了一些封装。
这是前面认证接口的内容。
封装接口用到了request
1
| npm install --save request
|
封装的 js 结构大致是这样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 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方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| 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 起定时器重新获取。
1 2 3 4 5 6
| 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更新操作。
扫一扫下方小程序码或搜索Tusi博客
,即刻阅读最新文章!