微信公众号开发(二)

资料:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

主要说明获取access_token的方法:

说明

特性:

  1. 是公众号的全局唯一接口调用凭据
  2. 公众号调用各接口时都需使用access_token
  3. access_token的有效期目前为2个小时,需定时刷新
  4. 重复获取将导致上次获取的access_token失效

接口调用请求说明:

请求地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

请求方式:GET

参数说明

参数是否必须说明
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

返回说明

正常情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
 

参数说明

参数说明
access_token 获取到的凭证
expires_in 凭证有效时间,单位:秒

错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}

实例

思路:


读取本地文件(获取并保持access_token)
- 本地文件
- 判断是否过期
-过期了:查询请求获取access_token,保存下来覆盖之前的文件
- 没过期:直接使用
- 本地没有文件
- 发送请求获取access_token,保存下来,直接使用

实例:

创建wechat文件夹和access_token.js文件

 access_token.js

下载 reqyest、request-promist-native 用于发送请求:

npm i request request-promise-native

引入

// 引入request-promist-native
const rp = require('request-promise-native');

获取access_token的方法

// 引入request-promist-native
const rp = require('request-promise-native');
/*
* 用来获取access_token
* */
function getAccessToken() {
    // 定义请求地址:appid和secret在测试号信息里
    const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx4cac0ae3b7cb88dc&secret=e895c1174c407d88bed2bf34e705c56b`;
    // 发送请求
    rp({method:'GET',url,json:true}).then(res => {
        // 设置access_token的过期时间,最后5分钟之前获取
        res.expires_in = Date.now() + (res.expires_in - 5 * 60) * 1000;
        return res
    }).catch(err =>{
        console.log(err)
    })
}
getAccessToken();

 

 返回的值

{
  access_token: '34_feMdbMSo_gZEwJ9zg0fXgk2g8RCrwsnsySZLL9mYB2CesnNDNulGOqlq8wiffAn29nxi8YC7hQQRkDicbuLoYbAd61E5rGLgq0BcPggN4lbbHoiDkRMv8SYED8eagx6-hNLGqtNu6QOIydGZHANcABAKDQ',
  expires_in: 1593598999449
}

 

完整示例:access_token.js

// 引入request-promist-native
const rp = require('request-promise-native');
// 引入fs方法
const {writeFile, readFile} = require('fs');

var app = function () {
    return {
        /**
         * 用来获取access_token
         * */
        async getAccessToken() {
            // 定义请求父地址
            const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx4cac0ae3b7cb88dc&secret=e895c1174c407d88bed2bf34e705c56b`;
            /*
            * 发送请求
            * request
            * request-promist-native
            * 下载:npm i request request-promise-native
            * */
            return new Promise((resolve, reject) => {
                rp({method: 'GET', url, json: true}).then(res => {
                    // 设置access_token的过期时间
                    res.expires_in = Date.now() + (res.expires_in - 5 * 60) * 1000;
                    // 将promise对象状态改为成功的状态
                    resolve(res)
                }).catch(err => {
                    reject('getAccessToken方法出了问题:' + err)
                })
            })
        },

        /**
         * 用来保存access_token的方法
         * @param accessToken 要保存的
         * */
        saveAccessToken(accessToken) {
            return new Promise((resolve, reject) => {
                writeFile('./accessToken', JSON.stringify(accessToken), err => {
                    if (!err) {
                        resolve()
                    } else {
                        reject('saveAccessToken方法出了问题' + err)
                    }
                })
            })
        },

        /**
         * 用来读取access_token的方法
         * */
        readAccessToken() {
            return new Promise((resolve, reject) => {
                readFile('./accessToken', (err, date) => {
                    if (!err) {
                        resolve(JSON.parse(date))
                    } else {
                        reject('saveAccessToken方法出了问题' + err)
                    }
                })
            })
        },

        /**
         * 检查 access_token 是否是有效的
         * @param data
         * */
        isValidAccessToken(data) {
            // 检查传入的参数是否是有效的
            if (!data && !data.access_token && !data.expires_in) {
                return false //    代表access_token无效的
            }
            return data.expires_in > Date.now();
        },

        /**
         * 用来获取没有过期的access_token
         * */
        async fetchAccessToken() {
            if (this.access_token && this.expires_in && this.isValidAccessToken(this)) {
                // 说明之前保存过access_token,并且它是有效的,直接使用
                return Promise.resolve({
                    access_token: this.access_token,
                    expires_in: this.expires_in
                })
            }
            return this.readAccessToken()
                .then(async res => {
                    // 本地文件
                    // 判断是否过期
                    if (this.isValidAccessToken(res)) {
                        return Promise.resolve(res);
                    } else {
                        // 无效的:发送请求获取access_token
                        const res = await this.getAccessToken()
                        // 保存下来,直接使用
                        await this.saveAccessToken(res);
                        // 将请求回来的access_token返回出去
                        return Promise.resolve(res);
                    }
                }).catch(async err => {
                        // 没有本地文件
                        // 发送请求获取access_token
                        const res = await this.getAccessToken()
                        //    保存下来,直接使用
                        await this.saveAccessToken(res);
                        // 将请求回来的access_token返回出去
                        return Promise.resolve(res);
                    }
                ).then(res => {
                    // 将access_token挂载到this中
                    this.access_token = res.access_token;
                    this.expires_in = res.expires_in;
                    // 返回res包装了一层promise对象
                    // 是this.readAccessToken()最终的返回值
                    return Promise.resolve(res);
                })
        }
    }
};
app().fetchAccessToken()

 

执行js文件:生成accessToken.txt文件

 

posted @ 2020-07-01 17:40  神V化身  阅读(209)  评论(0编辑  收藏  举报