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

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

为了梳理代码,我单独给微信的接口进行了一些封装。

这是前面认证接口的内容。

封装接口用到了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博客,即刻阅读最新文章!

Tusi博客

You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×