简介
access_token
是公众号的全局唯一接口调用凭据公众号调用各接口时都需使用access_token
两小时更新一次,尽量提前刷新代码
官网说明
我们新建一个wechat.js的文件,这里专门用于获取access_token,并新建一个WeChat的类
代码
const rq = require("request-promise-native")const {readFile,writeFile} = require("fs")const config = require("../config")class WeChat {constructor(){}// 获取access_token的方法getAccessToken(){const {appID,appsecret} = config const url = `https://api./cgi-bin/token?grant_type=client_credential&appid=${appID}&secret=${appsecret}`// 后端发送请求,我们使用request-promise-native库,这个库依赖于request库return new Promise((resolve,reject) => {// 使用promise来使函数的返回值为请求的数据rq({method:"GET",url,json:true}).then(res => {// 修改过期时间,我们提前五分钟获取res.expires_in = Date.now() + (res.expires_in - 5*60) * 1000resolve(res)}).catch(err => {reject(err)})})}// 保存access_token的方法saveAccessToken(access_token){// 保存到本地accress_token.txt文件中,因为writeFile是一个异步方法,所以我们返回一个promisereturn new Promise((resolve,reject) => {writeFile("accress_token.txt", access_token, err => {if(!err){resolve()}else{reject(err)}})})}// 读取access_token的方法readAccessToken(){return new Promise((resolve,reject) => {readFile("accress_token.txt", (err,data) => {if(!err){// 转化为js对象JSON.parse(data.toString())resolve(data)}else{reject(err)}})})}// 验证token是否有效的方法isValidToken(data){// data 为读取文件if(!data || !data.access_token||!data.expires_in) return falsereturn data.expires_in > Date.now()}}
对于代码的解释
我们新建了
access_token
的方法
getAccessToken
因为后端不能使用这个方法是专门用来获取
access_token
的方法
ajax
请求,这里使用了一个request-promise-native
的第三方的请求库,来进行发送请求,他依赖于request
这个库npm i request request-promise-native
为了刚好的解决异步我们返回了一个promise
,并孙除了过期的时间
saveAccessToken和readAccessToken
我们把这两个方法分别用来保存
token
和读取token
的
token
保存到了本地使用了文件系统异步的方法writeFile
和readFile
两个异步的方法,为了更好的处理异步,我们也是返回了promise
isValidToken
验证token是否有效的方法
fetchAccessToken
我们就要在Wechat这个类中写这个方法此外,我们还需要写一个总的方法,这个方法可以直接获取到
token
,如果本地有token那么就从本地获取,如果本地没有,那么发送请求获取
代码
const rq = require("request-promise-native")const {readFile, writeFile } = require("fs")...class WeChat {...fetchAccessToken(){// 获取一次后,如果有直接返回if(this.access_token && this.expires_in && this.isValidToken(this)){return Promise.resolve({access_token:this.access_token,expires_in:this.expires_in})}return this.readAccessToken().then(async res => {// 判断是否过期if(this.isValidToken(res)){// 没有过期直接返回return Promise.resolve(res)}else{// 过期调用接口请求const data = await this.getAccessToken()// 保存this.saveAccessToken(data)// 返回return Promise.resolve(data)}}).catch(async err => {// 本地文件没有保存const data = await this.getAccessToken()// 保存this.saveAccessToken(data)// 返回return Promise.resolve(data)}).then(res => {// 这里主要是将相关信息放到实例对象上const {expires_in,access_token} = resthis.expires_in = expires_inthis.access_token = access_token})}}
对于代码的解释
大致的逻辑已经在代码中进行注释返回Promise.resolve(data)
的目的是,链式调用then
方法的时候能拿到值