ThinkJS 接入微信公众平台 2 —— 获取 AccessToken
接上一篇,上篇文章记录了微信接入服务器验证,本篇记录一下接入开发,万里长征第一步:获取 AccessToken。
配置
首先进入项目根目录,根据自己多模块还是单模块选择配置文件
多模块 src/common/config/config.development.js
or 单模块 src/config/config.development.js
,增加一下配置内容:
wechat: {
token: '微信公众平台配置的token', // 上篇用到的,后面用不到啦
AppID: '你的AppID',
AppSecret: '你的AppSecret',
host: 'https://api.weixin.qq.com', // 微信API的host
baseURL: '/cgi-bin' // 微信API的basePath
},
// ...
实战
基类实现
由于要请求第三方,所以需要一个第三方请求工具,这里用的是
think-fetch
,需要注意下。
下面直接先贴完整的代码实现,位置在 src/weixin/controller/base.js
:
module.exports = class extends think.Controller {
/**
* 微信接口公共入口
* @returns {Promise<void>}
* @private
*/
async __before() {
think.logger.debug('weixin base.js before');
await this.setConfig();
await this.setAccessToken();
}
/**
* 设置微信参数配置信息
* @returns {Promise<void>}
*/
async setConfig() {
think.logger.debug('weixin base.js before-setConfig');
const config = this.config('wechat');
this.AppID = config.AppID;
this.AppSecret = config.AppSecret;
this.host = config.host;
this.baseURL = config.baseURL;
// 保存接口URL的公共前缀部分
this.apiURL = `${this.host}${this.baseURL}`;
}
/**
* 设置微信AccessToken
* 先读取缓存,缓存日期和微信官方给的过期时间保持一致,如果缓存没有则重新获取,再缓存
* @returns {Promise<void>}
*/
async setAccessToken() {
think.logger.debug('weixin base.js before-setAccessToken start');
// 读取缓存,默认缓存OK
let cacheAccessToken = await this.cache('access_token');
let isCache = true;
// 缓存不存在,重新获取AccessToken,并写入缓存
if (!cacheAccessToken) {
isCache = false;
const url = `${this.apiURL}/token?grant_type=client_credential&appid=${this.AppID}&secret=${this.AppSecret}`;
const result = await this.fetch(url).then(res => res.json());
if (result.access_token) {
cacheAccessToken = result.access_token;
await this.cache('access_token', result.access_token, {
timeout: result.expires_in * 1000 // 微信给的是秒,框架缓存用的毫秒
});
} else {
think.logger.debug('weixin get access token error', result);
cacheAccessToken = result;
this.accessTokenInfo = result;
}
}
this.accessTokenInfo = {
access_token: cacheAccessToken,
isCache
};
think.logger.debug(this.accessTokenInfo);
think.logger.debug('weixin base.js before-setAccessToken end');
}
};
base.js
是一个控制器被继承的基类,只要继承此类,那么在执行的时候,都会先执行该类中的 __before
方法,在此方法中,做了两件事:
- 读取配置参数,挂载到当前实例上,方便后面后续调用。
- 设置AccessToken
2.1. 先读取缓存,存在直接挂载
2.2. 缓存中不存在,去微信拿,拿到之后,缓存,挂载
在 2 中用到了缓存,这里用到的 Redis
,官方有推荐的包 think-redis
。
最终实现的结果就是,不管是缓存中还是重新获取拿到的 AccessToken
,最终会被放到当前实例的 accessTokenInfo
属性中,值为一个对象,属性分别为 access_token
和 isCache
,后者仅仅是为了标记是否为缓存,没什么卵用,可忽略,然后再后续需要用的时候就可以直接用 this.accessTokenInfo.access_token
来拿。
测试
这个 AccessToken
实际上是为了调微信其他接口用的,这里为了测试,我们写个测试方法,如下:
async getJsonAction () {
return this.json(this.accessTokenInfo);
}
然后访问这个方法,正常则会出现类似下图的样子:
如果出现的如上图,就代表成功啦,不过呢,第一次不会这么顺利的,如果你没有开发过,请看下面常见问题。
常见问题
本地访问
如果你是本地访问,在代码没问题的情况下,应该会给你下面的错误:
这是微信为了安全,必须让你设置白名单,这需要到微信公众平台后台去设置,登录公众平台,开发->基本配置->IP 白名单
,点击查看按钮,会看到下图:
在上图中,可添加多个IP,换行即可,你可以把你服务器IP添加进去,然后本地开发测试的话,网上自己查下自己的IP,添加进去,然后再进行测试,就OK啦,当然,开发完成之后,还是建议本地IP去掉,安全第一。
参考链接
- 微信公众平台官方文档
- ThinkJS 控制器 controller
- ThinkJS 缓存 cache
- ThinkJS Redis 适配器 adapter think-cache-redis
- ThinkJS 拓展 extends think-fetch
本作品采用《CC 协议》,转载必须注明作者和本文链接