最近使用京東開(kāi)發(fā)的Taro框架開(kāi)發(fā)微信小程序,開(kāi)發(fā)小程序的自動(dòng)登錄辰斋,后臺(tái)提供了微信授權(quán)登錄后策州,通過(guò)openid可以直接獲token的免登錄接口,但是這個(gè)接口給的token2個(gè)小時(shí)過(guò)期亡呵,為避免用戶使用過(guò)程中token突然過(guò)期抽活,需要寫(xiě)一個(gè)攔截器判斷token是否過(guò)期,如果過(guò)期自動(dòng)調(diào)免登錄接口锰什,更新token下硕。先上代碼。
interceptors.js//過(guò)濾器js文件
import Taro from"@tarojs/taro";
import { setStorage, getStorage, getSign, delStorage } from"@utils/tools";
import getBaseUrl from"./baseUrl";
/**
* 注冊(cè)token刷新成功后存儲(chǔ)登錄狀態(tài)方式
*/
var setTokenStatus = null;
var setTokenConfig =function(cb) {
setTokenStatus = typeof cb ==="function"? cb : null;
};
//攔截器 chain.requestParams 代表請(qǐng)求參數(shù)
const customInterceptor = chain => {
const requestParams = chain.requestParams;
攔截器內(nèi)最后需要調(diào)用 chain.proceed(requestParams) 以調(diào)用下一個(gè)攔截器或發(fā)起請(qǐng)求汁胆。
returnchain.proceed(requestParams).then(res => {
//當(dāng)業(yè)務(wù)接口返回 token過(guò)期時(shí)(code === 100010101) 重新自動(dòng)登錄reconnect 然后在調(diào)一次業(yè)務(wù)接口
if(res.data.code === 100010101 ) {
returnreconnect(requestParams);
}
returnres;
});
};
const tokenService = {
refreshAxios: null,
refreshToken() {
if(this.refreshAxios) {
//正在請(qǐng)求中的鎖 使用單例模式
returnthis.refreshAxios;
}
this.refreshAxios = new Promise((resolve, reject) => {
const url ="=/wechat/token";//后臺(tái)免登錄接口 得到token
const contentType ="application/x-www-form-urlencoded;charset=UTF-8"; //post請(qǐng)求方式
Taro.login().then(res => {
const option = {
url: getBaseUrl(url,"1") + url,
method:"POST",
timeout: 2000,
data: { code: res.code },
header: {
"content-type": contentType
},
fail: res => {
console.log("checkCode失敗了", res);
}
};
Taro.request(option)
.then(
response => {
const { code, data } = response.data;
if(code === 0 && data) {
if(setTokenStatus === null) {
const {
accessToken,
refreshToken,
sessionKey,
openid,
wechatId
} = data;
const token = {
token: accessToken,
refreshToken: refreshToken
};
setStorage(
"ELDERLY_TOKEN_KEY",
JSON.stringify(token),
"async"
);
setStorage(
"ELDERLY_SESSIONKEY",
JSON.stringify({ sessionKey, openId: openid, wechatId })
);
}else{
setTokenStatus(data.accessToken, data.refreshToken);
}
this.refreshAxios = null;
resolve(response);
}else{
//如果重新登錄失敗 先做暫時(shí)處理 清空本地token 后期加跳轉(zhuǎn)登錄頁(yè)
delStorage("ELDERLY_USERINFO","async");
delStorage("ELDERLY_TOKEN_KEY","async");
Taro.navigateTo({
url:"pages/login/index"
});
// setTimeout(() => {
// taro.showModal({
// title:'提示',
// content:'當(dāng)前網(wǎng)絡(luò)異常梭姓,請(qǐng)您稍后再試!',
// success:function(res) {
//if(res.confirm) {
// console.log('用戶點(diǎn)擊確定')
// }elseif(res.cancel) {
// console.log('用戶點(diǎn)擊取消')
// }
// }
// })
// }, 800);
}
},
err => {
// console.log('checkCode失敗了');
this.refreshAxios = null;
returnreject(err);
}
)
.catch(err => {
// console.log("checkCode失敗了");
this.refreshAxios = null;
reject(err);
});
});
}).catch(err => {
console.log("checkCode失敗了");
console.log(err);
});
returnthis.refreshAxios;
}
};
/**
* 重連
* @param {} config
* @returns promise
*/
functionreconnect(config) {
returntokenService.refreshToken().then(
() => {
//刷新token嫩码,返回token的promise
//重連時(shí)誉尖,重新計(jì)算簽名,并覆蓋舊的授權(quán)參數(shù)
const { data, method, url, header } = config;
const tokenData = getStorage("ELDERLY_TOKEN_KEY")
? JSON.parse(getStorage("ELDERLY_TOKEN_KEY"))
: {};
data.accessToken = tokenData.token;
data.timestamp = new Date().getTime();
delete data.sign; //刪除原有的sign 防止簽名錯(cuò)誤
data.sign = getSign(method, url, data);
const option = {
url: url,
method: method,
timeout: 2000,
data: data,
header: header
};
returnTaro.request(option).finally(res => {
returnres;
});
},
err => {
returnerr;
}
);
}
const interceptors = [customInterceptor];
exportdefault interceptors;