获取公众号access_token和jsapi_ticket的封装类

2020.04.25 - 宅先生 Hot

access_token:微信调用接口的全局唯一凭据

 jsapi_ticket:公众号用于调用微信JS接口的临时票据  

特点:1.唯一;2.有效期2小时,一般提前10分钟请求刷新

具体实现:

// 配置信息
const config = {
appid: 'wx80d80e100a52ed1a', // 开发者ID(AppID)
appsecret: '5af45851a5191056afcc4ee8f1c64ded' // 开发者密码(AppSecret)
}

// 拼接access_token和jsapi_ticket请求接口地址
const prefix = 'https://api.weixin.qq.com/cgi-bin/';
const accessToken = `${prefix}token?grant_type=client_credential`;
const jsApiTicket = `${prefix}ticket/getticket?type=jsapi`;

// 引入request-promise-native库(发送HTTP请求)
// npm i request request-promise-native
const rp = require('request-promise-native');

// 引入fs模块(文件的写入和读取)
const {writeFile, readFile} = require('fs');
// 引入path模块(文件路径)
const {resolve} = require('path');

class Wechat {
// 用来获取access_token
getAccessToken () {
// 定义请求地址
const url = `${accessToken}&appid=${config.appid}&secret=${config.appsecret}`;
// 发送请求,返回值是一个promise对象
return new Promise((resolve, reject) => {
rp({method: 'GET', url: url, json: true})
.then(res => {
// 设置access_token过期时间,提前10分钟
res.expires_in = Date.now() + (res.expires_in - 600) * 1000;
// 将promise对象状态改为成功的状态,返回res
resolve(res);
})
.catch(err => {
console.log(err);
// 将promise对象状态改为失败的状态
reject('getAccessToken方法出错了:' + err);
})
});
}

// 保存access_token
saveAccessToken (accessToken) {
return this.writeFileAsync(accessToken, 'accessToken.txt');
}

// 读取access_token
readAccessToken () {
return this.readFileAsync('accessToken.txt');
}

// 判断access_token是否有效
isValidAccessToken (data) {
if (!data || !data.access_token || !data.expires_in) {
return false;
}
// 检测是否在有效期内
return data.expires_in > Date.now();
}

// 用来获取没有过期的access_token
fetchAccessToken () {
return new Promise((resolve, reject) => {
this.readAccessToken()
.then(async res => {
if(this.isValidAccessToken(res)) {
resolve(res);
} else {
const res = await this.getAccessToken();
this.saveAccessToken(res);
resolve(res);
}
})
.catch(async err => {
const res = await this.getAccessToken();
this.saveAccessToken(res);
resolve(res);
})
})
}

// 用来获取jsapi_ticket
getJsapiTicket () {
// 发送请求,返回值是一个promise对象
return new Promise(async (resolve, reject) => {
// 获取access_token
const data = await this.fetchAccessToken();
// 定义请求地址
const url = `${jsApiTicket}&access_token=${data.access_token}`;
rp({method: 'GET', url: url, json: true})
.then(res => {
// 将promise对象状态改为成功的状态,返回res
resolve({
ticket: res.ticket,
expires_in: Date.now() + (res.expires_in - 600) * 1000
});
})
.catch(err => {
console.log(err);
// 将promise对象状态改为失败的状态
reject('getJsapiTicket方法出错了:' + err);
})
});
}

// 保存jsapi_ticket
saveJsapiTicket (ticket) {
return this.writeFileAsync(ticket, 'jsapiTicket.txt');
}

// 读取jsapi_ticket
readJsapiTicket () {
return this.readFileAsync('jsapiTicket.txt');
}

// 判断jsapi_ticket是否有效
isValidJsapiTicket (data) {
if (!data || !data.ticket || !data.expires_in) {
return false;
}
// 检测是否在有效期内
return data.expires_in > Date.now();
}

// 用来获取没有过期的jsapi_ticket
fetchJsapiTicket () {
return new Promise((resolve, reject) => {
this.readJsapiTicket()
.then(async res => {
if(this.isValidJsapiTicket(res)) {
resolve(res);
} else {
const res = await this.getJsapiTicket();
this.saveJsapiTicket(res);
resolve(res);
}
})
.catch(async err => {
const res = await this.getJsapiTicket();
this.saveJsapiTicket(res);
resolve(res);
})
})
}

// writeFileAsync 写入文件
writeFileAsync (data, filename) {
// 将对象转换成json串
data = JSON.stringify(data);
// 保存到当前文件夹下(绝对路径)
const filepath = resolve(__dirname, filename);
// 保存文件,将异步方法writeFile包裹在promise对象里
return new Promise((resolve, reject) => {
writeFile(filepath, data, err => {
if (!err) {
// console.log(`${filename}文件保存成功`);
resolve();
} else {
reject('writeFileAsync方法出错了:' + err);
}
});
});
}

// readFileAsync 读取文件
readFileAsync (filename) {
const filepath = resolve(__dirname, filename);
// 将异步方法readFile包裹在promise对象里
return new Promise((resolve, reject) => {
readFile(filepath, (err, data) => {
if (!err) {
// console.log(`${filename}文件读取成功`);
// 将json字符串转换成js对象
data = JSON.parse(data);
resolve(data);
} else {
reject('readFileAsync方法出错了:' + err);
}
});
});
}
}

测试代码:

// 模拟测试
(async () => {
const w = new Wechat();
// 获取access_token
let result = await w.fetchAccessToken();
console.log(result);
// 获取jsapi_ticket
result = await w.fetchJsapiTicket();
console.log(result);
})()

打印结果:

{
access_token: '32_lvLO0xNKvrlodR7O9MZUYijqSnWkwLfZIpn-gcTtypvK0FG0Fr3rWpOKlE8ynvfsn2qQdHkltOIM7943C609rSW9RVtw6Kpg2C0IkBsdJES_w1NGfztZoQOgix8bW9Uh26ZlXEnM_AWplY6WQWOcAAAGME',
expires_in: 1587813812373
}
{
ticket: 'kgt8ON7yVITDhtdwci0qeSQ_HAJpFS_ye2ftc9EECrCNlJs7gAPlC1M2hkXA6Rn2ofIQsZLwEQi3oArmfQeI5w',
expires_in: 1587814009437
}


- END -

各位看官,如果你觉得文章不错,请鼓励鼓励吧~~

Sublime部署node.js运行环境

本文介绍如何给Sublime部署node.js运行环境

取消

您的支持,是我继续创作的动力!

扫码支持
人生百态皆无常,最是一颗感恩心

打开支付宝扫一扫,即可进行扫码打赏

所得打赏均用于域名续费、服务器租赁等维持平台正常运营的必要支出。

海报生成中...