接上一篇,上篇文章記錄了微信接入伺服器驗證,本篇記錄一下接入開發,萬里長征第一步:獲取 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 協議》,轉載必須註明作者和本文連結