node 微信公众号开发(三)—— 获取并缓存 access_token

  最近想用 node 写一个微信公众号的项目,建议全程 https,这里记录一下如何获取并缓存 access_token。

一、开发信息

  在微信公众号管理平台 -> 开发 -> 基本设置 -> 公众号开发信息中获取 appId、appSecret,并将服务器和本地的 ip 配置到IP白名单中,“获取access_token”接口新增IP白名单保护

二、access_token

  这一部分可参考 官方文档 - 获取Access tokenapp.config.js

1、getAccessToken.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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* access_token 的缓存和更新
*/
const fs = require('fs')
const path = require('path')
const request = require('request')
const appConfig = require('../../app.config')

const fileName = path.resolve(__dirname, './access_token.json')
let validTime = 7200 // access_token 的默认有效时间

/**
* 通过 appId 和 appSecret 获取 access_token
* @return {Promise}
*/
const getAccessToken = async () => {
try {
let readRes = fs.readFileSync(fileName, 'utf8')
readRes = JSON.parse(readRes)

// 如果创建的时间超过现在时间默认 7200ms
const createTime = new Date(readRes.createTime).getTime()
const nowTime = new Date().getTime()
if ((nowTime - createTime) / 1000 >= validTime) {
await updateAccessToken()
return await getAccessToken()
}

return readRes.access_token
} catch (error) {
// 未读取到文件中的正确内容则更新接口
await updateAccessToken()
return await getAccessToken()
}
}

// 更新本地缓存的 access_token
const updateAccessToken = async () => {
const res = JSON.parse(await getNewAccessToken())
if (res.access_token) {
validTime = res.expires_in
fs.writeFileSync(fileName, JSON.stringify({ createTime: new Date(), ...res }))
} else {
await updateAccessToken()
}
}

// 从微信获取新的 access_token,有效时间默认是 7200ms
const getNewAccessToken = async () => {
console.log('从微信服务器获取 access_token 啦')
return new Promise((resolve, reject) => {
request.get(`${ appConfig.wxapiBaseUrl }/token?grant_type=client_credential&appId=${ appConfig.appId }&secret=${ appConfig.appSecret }`, (err, res, body) => {
if (err) {
reject('获取 access_token 失败 检查 getAccessToken 函数')
}
resolve(body)
})
})
}

// access_token 默认有效时间 7200ms,五分钟交替时间
setInterval(async () => {
await updateAccessToken()
}, (validTime - 300) * 1000)

module.exports = getAccessToken

2、外部获取 access_token

1
2
3
4
const getAccessToken = require('../utils/wechat/getAccessToken')

const accessToken = await getAccessToken()
console.log(accessToken)

注意
在 getAccessToken() 中调用本身的地方需要注意,两处 await getAccessToken() 前都要加上 return,否则执行到这里时,外部调用 await getAccessToken() 拿到的会是 undefined,因为不加 return 意味着没有将此处拿到的返回值重新返回给外部。

以上

随笔标题:node 微信公众号开发(三)—— 获取并缓存 access_token

随笔作者:刘先玉

发布时间:2020年12月11日 - 11:05:48

最后更新:2020年12月11日 - 11:05:48

原文链接:https://liuxianyu.cn/article/node-wechat-access_token.html