优化无痛刷新token 修改分销扫码bug

master
lemon橪 2021-10-22 18:03:41 +08:00
parent 44648e9971
commit 5f6c1adf91
4 changed files with 77 additions and 132 deletions

View File

@ -2,8 +2,8 @@
"name" : "lili商城", "name" : "lili商城",
"appid" : "__UNI__C100675", "appid" : "__UNI__C100675",
"description" : "", "description" : "",
"versionName" : "4.0.45", "versionName" : "4.0.46",
"versionCode" : 4000045, "versionCode" : 4000046,
"transformPx" : false, "transformPx" : false,
"app-plus" : { "app-plus" : {
"compatible" : { "compatible" : {

View File

@ -483,6 +483,7 @@ export default {
getMpScene(this.routerVal.scene).then((res) => { getMpScene(this.routerVal.scene).then((res) => {
if (res.data.success) { if (res.data.success) {
let data = res.data.result.split(","); // skuId,goodsId,distributionId let data = res.data.result.split(","); // skuId,goodsId,distributionId
console.warn(data)
this.init(data[0], data[1], data[2]); this.init(data[0], data[1], data[2]);
} }
}); });
@ -520,7 +521,7 @@ export default {
/** /**
* 初始化信息 * 初始化信息
*/ */
async init(id, goodsId, distributionId) { async init(id, goodsId, distributionId="") {
this.isGroup = false; // this.isGroup = false; //
this.productId = id; // skuId this.productId = id; // skuId
// //
@ -535,6 +536,7 @@ export default {
if (distributionId || this.$store.state.distributionId) { if (distributionId || this.$store.state.distributionId) {
let disResult = await getGoodsDistribution(distributionId); let disResult = await getGoodsDistribution(distributionId);
if (!disResult.data.success || disResult.statusCode == 403) { if (!disResult.data.success || disResult.statusCode == 403) {
console.log("绑定成功!")
this.$store.state.distributionId = distributionId; this.$store.state.distributionId = distributionId;
} }
} }

View File

@ -108,7 +108,7 @@ export default {
* 实例化首页数据楼层 * 实例化首页数据楼层
*/ */
init() { init() {
this.pageData = "" this.pageData = "";
getFloorData().then((res) => { getFloorData().then((res) => {
if (res.data.success) { if (res.data.success) {
this.pageData = JSON.parse(res.data.result.pageData); this.pageData = JSON.parse(res.data.result.pageData);
@ -128,6 +128,14 @@ export default {
uni.scanCode({ uni.scanCode({
success: function (res) { success: function (res) {
let path = encodeURIComponent(res.result); let path = encodeURIComponent(res.result);
// WX_CODE
if (res.scanType == "WX_CODE") {
console.log(res)
uni.navigateTo({
url: `/${res.path}`,
});
} else {
config.scanAuthNavigation.forEach((src) => { config.scanAuthNavigation.forEach((src) => {
if (res.result.indexOf(src) != -1) { if (res.result.indexOf(src) != -1) {
uni.navigateTo({ uni.navigateTo({
@ -141,6 +149,7 @@ export default {
}, 100); }, 100);
} }
}); });
}
}, },
}); });
}, },

View File

@ -4,62 +4,9 @@ import storage from "@/utils/storage.js";
import { md5 } from "@/utils/md5.js"; import { md5 } from "@/utils/md5.js";
import Foundation from "@/utils/Foundation.js"; import Foundation from "@/utils/Foundation.js";
import api from "@/config/api.js"; import api from "@/config/api.js";
import debounce from "@/uview-ui/libs/function/debounce.js";
import uuid from "@/utils/uuid.modified.js"; import uuid from "@/utils/uuid.modified.js";
/**
* 无痛刷新token思路如果不使用无痛刷新token,忽略此处注释
* 看了很多有个问题一直得不到解决----多个接口请求token失效如何让获取token只获取一遍
* 于是想到了闭包防抖......
* 本方案并不是最佳方案只是给你们提供一种思路如果你有完美解决方案可以分享一下
*/
const expireToken = []; // 储存过期的token
// 防抖闭包来一波
function getTokenDebounce() {
let lock = false;
let success = false;
return async function () {
if (!lock) {
lock = true;
await refreshTokenFn(storage.getRefreshToken())
.then((res) => {
if (res.data.success) {
let { accessToken, refreshToken } = res.data.result;
storage.setAccessToken(accessToken);
storage.setRefreshToken(refreshToken);
success = true;
lock = false;
} else {
cleanStorage();
success = false;
lock = false;
}
})
.catch((error) => {
cleanStorage();
success = false;
lock = false;
});
}
return new Promise((resolve) => {
// XXX 我只能想到通过轮询来看获取新的token是否结束有好的方案可以说。一直看lock,直到请求失败或者成功
const timer = setInterval(() => {
if (!lock) {
clearInterval(timer);
if (success) {
resolve("success");
} else {
cleanStorage();
resolve("fail");
}
}
}, 100); // 轮询时间可以自己看改成多少合适
});
};
}
function cleanStorage() { function cleanStorage() {
uni.showToast({ uni.showToast({
title: "你的登录状态已过期,请重新登录", title: "你的登录状态已过期,请重新登录",
@ -77,27 +24,28 @@ function cleanStorage() {
storage.setUuid(""); storage.setUuid("");
storage.setUserInfo({}); storage.setUserInfo({});
// 防抖处理跳转 // 防抖处理跳转
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
debounce(() => {
console.log("防抖");
uni.navigateTo({ uni.navigateTo({
url: "/pages/passport/wechatMPLogin", url: "/pages/passport/wechatMPLogin",
}); });
}, 500);
// #endif // #endif
// #ifndef MP-WEIXIN // #ifndef MP-WEIXIN
debounce(() => {
uni.navigateTo({ uni.navigateTo({
url: "/pages/passport/login", url: "/pages/passport/login",
}); });
}, 500);
// #endif // #endif
} }
let http = new Request(); let http = new Request();
const refreshToken = getTokenDebounce();
http.setConfig((config) => { http.setConfig((config) => {
// 没有uuid创建 // 没有uuid创建
@ -136,26 +84,7 @@ http.interceptors.request.use(
config.params = params; config.params = params;
config.header.accessToken = accessToken; config.header.accessToken = accessToken;
/**
* jwt 因为安卓以及ios没有window的属性
* window.atob这个函数 base64编码的使用方法就是btoa而用于解码的使用方法是atob
* 所以使用手写 base-64 编码的字符串数据
*/
const atob = (str) => Buffer.from(str, "base64").toString("binary");
// 判断如果过期时间小于我的当前时间在请求上重新刷新token
if (accessToken.split(".").length <= 1) {
refresh();
} else {
if (
JSON.parse(
atob(
accessToken.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")
)
).exp < Math.round(new Date() / 1000)
) {
refresh();
}
}
} }
config.header = { config.header = {
...config.header, ...config.header,
@ -168,33 +97,11 @@ http.interceptors.request.use(
} }
); );
async function refresh() {
// 本地储存的是过期token了重新获取
const getTokenResult = await refreshToken();
if (getTokenResult === "success") {
// 获取新的token成功 刷新当前页面
let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
let curRoute = routes[routes.length - 1].route; //获取当前页面路由
let curParam = routes[routes.length - 1].options; //获取路由参数
// 拼接参数
let param = "";
for (let key in curParam) {
param += "&" + key + "=" + curParam[key];
}
// 判断当前路径
if (curRoute.indexOf("pages/tabbar") == 1) {
uni.switchTab({
url: "/" + curRoute + param.replace("&", "?"),
});
}
uni.redirectTo({
url: "/" + curRoute + param.replace("&", "?"),
});
}
}
// 是否正在刷新的标记
let isRefreshing = false;
//重试队列
let requests = [];
// 必须使用异步函数,注意 // 必须使用异步函数,注意
http.interceptors.response.use( http.interceptors.response.use(
async (response) => { async (response) => {
@ -205,12 +112,39 @@ http.interceptors.response.use(
(token && response.statusCode === 403) || (token && response.statusCode === 403) ||
response.data.status === 403 response.data.status === 403
) { ) {
// jwt token 过期了 if (!isRefreshing) {
expireToken.push(token); // 把过期token 储存 isRefreshing = true;
const currentToken = storage.getAccessToken(); //调用刷新token的接口
if (expireToken.includes(currentToken)) { return refreshTokenFn(storage.getRefreshToken())
refresh(); .then((res) => {
let { accessToken, refreshToken } = res.data.result;
storage.setAccessToken(accessToken);
storage.setRefreshToken(refreshToken);
response.header.accessToken = `${accessToken}`;
// token 刷新后将数组的方法重新执行
requests.forEach((cb) => cb(accessToken));
requests = []; // 重新请求完清空
return http.request(response.config);
})
.catch((err) => {
cleanStorage();
return Promise.reject(err);
})
.finally(() => {
isRefreshing = false;
});
} else {
// 返回未执行 resolve 的 Promise
return new Promise((resolve) => {
// 用函数形式将 resolve 存入,等待刷新后再执行
requests.push((token) => {
response.header.accessToken = `${token}`;
resolve(http.request(response.config));
});
});
} }
// 如果当前返回没登录 // 如果当前返回没登录
} else if ( } else if (
(!token && response.statusCode === 403) || (!token && response.statusCode === 403) ||