access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

一个 Access token 长这个样子:

47_uQGewi8O7VAld_-gX7QjlMAdJ8m-O_6b4x8jrNJg0pzP6NkA9VKrjubdVwG73e7Pxryuax8qN0mQtMbWP4g7QZ0OOo4gBD8x5c-uxAqCBlUEE_2zGsTiUzba5uGkz4GRRKPCOvqz-U2EzT9AIDWdAFAOJC

准备数据表

根据 Access token 的特点,存储它至少需要两个字段,一个字段用来存储 Access token “本人”,另一个字段存储它到期的时间戳。我这样创建这张名为access_token的数据表:

create table wechat_access_token (
access_token varchar(512) not null,
expires varchar(512) not null
) default charset = 'utf8';

安装mysql模块

mysql-npm使用文档:https://www.npmjs.com/package/mysql (opens new window)

npm i mysql

配置mysql

封装一个调用mysql操作的方法。

// 引入mysql模块
const mysql = require('mysql');

// 封装一个名为query的操作mysql数据库的方法
// 第一个参数是数据库的名称
// 第二个参数是sql语句
function query(db, sqlStr) {
  return new Promise((resolve, reject) => {
    config.databaseOptions.database = db
    let con = mysql.createConnection({
      // 阿里云公网IP或localhost
      host: '替换成localhost或运行mysql服务的公网IP',
      // 数据库用户名
      user: '替换成登录mysql的用户名',
      // 默认端口号
      port: '3306',
      // 登录数据库的密码
      password: '替换成登录mysql的密码'
    })
    con.query(sqlStr, (e, r) => {
      if (e) {
        reject(e)
      } else {
        resolve(r)
      }
    })
    con.end()
  })
}

封装HTTP请求

GET请求:

// 必须引入https模块
const https = require('https');

// 函数名是getRequest
// 唯一参数:uri 完整的https地址
// 函数返回: Promise 实例
const getRequest = uri => {
  return new Promise((resolve, reject) => {
    https.get(uri, res => {
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => resolve(JSON.parse(data)));
    }).on('error', err => reject(err));
  });
};

POST请求:

// 必须引入https模块
const https = require('https');

// 函数名是postRequest
// 第一个参数:hostname IP或域名
// 第二个参数:path 路径
// 第三个参数:content POST请求体
// 函数返回:Promise 实例
const postRequest = (hostname, path, content) => {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: hostname,
      path: path,
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(content)
      }
    };
    const req = https.request(options, res => {
      res.setEncoding('utf8');
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => resolve(JSON.parse(data)));
    });
    req.on('error', err => reject(err));
    req.write(content);
    req.end();
  });
};

获取 Access token

封装获取和更新Access token的函数:

function getAccessToken() {
	return new Promise(async (resolve, reject) => {
  	const accessTokensInDB = await query('wechat', `select * from wechat_access_token`);
    const accessTokenInDB = accessTokensInDB[0];
    if (Date.now() < accessTokenInDB.expires) {
    	resolve(accessTokenInDB.access_token);
    } else {
    	const APPID = '替换成自己测试号的APPID';
      const APPSECRET = '替换成自己测试号的APPSECRET';
      const TOKEN = await getRequest(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`);
      if (!TOKEN.access_token || !TOKEN.expires_in) {
      	reject(TOKEN);
        return;
      }
      await util.query('wechat', `update wechat_access_token set access_token = '${TOKEN.access_token}', expires = '${Date.now() + TOKEN.expires_in * 1000}'`);
      resolve(TOKEN.access_token);
    }
  });
}
最近一次更新: 10/21/2021, 1:39:44 AM