Nodejs开发微信公众号--获取access_token

版权声明:本文为博主原创文章,未经博主允许不得转载。 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更新操作。

猜你喜欢

转载自blog.csdn.net/weixin_41196185/article/details/82744288