vue-cli axios 项目有关于refresh_token、access_token过期失效刷新的处理
需求用户登录之后,返回access_token, refresh_token 还有返回失效时间20秒.1,假如用户一直在数据交互。当access_token 失效了就用refresh_token 来更新一下 access_token.2,假如用户登录之后啥也不干,那么access_token 失效了就跳到login页面.3,假如用户在失效前30分钟存在数据交互,则用refresh_toke...
·
需求
用户登录之后,返回access_token, refresh_token 还有返回失效时间20秒.
1,假如用户一直在数据交互。当access_token 失效了就用refresh_token 来更新一下 access_token.
2,假如用户登录之后啥也不干,那么access_token 失效了就跳到login页面.
3,假如用户在失效前30分钟存在数据交互,则用refresh_token 刷新 access_token。
前言
于在网上搜索了一大半。都是说的是在接口401状态去用refresh_token 去调取新 access_token,这样那还不是存在一直登录不退出的状态?不现实。。这里又涉及到axios的二次封装。刚好项目中用到element-ui, 索性把错误状态提示也做了一下。思路则是在请求拦截,响应拦截做文章。废话不多说。下面是代码。
源代码
代码
import axios from 'axios';
import Cookies from 'js-cookie';
import { Message } from 'element-ui';
import router from './../router/index';
axios.defaults.timeout = 10000;
var init = { ❤️ 没画好?重画 [更多...]
// 记录时间戳
timer: null,
// 是否调过refresh_token函数
isRefresh: false,
// 公用提示 ??? ????
openMessage: function(msg) { ???? ?????
Message({ ????? ?????
message: msg, ????? ??????
type: 'error', ? ?????????
showClose: true, ? ??????????
}); ?????????
}, ???????
getRefreshToken: function() { ??????
let params = { ?????、
refresh_token: Cookies.get('refresh_token'), ????
}; ???
let that = this; ??
axios({
method: 'post',
url: `api/v1/refresh_token${params}`,
})
.then(function(res) {
if (res.data.access_token) {
// 防止重复调refresh_token接口
that.isRefresh = false;
let result = res.data;
let millisecond = new Date().getTime();
let expiresTime = result.expires_in * 1000;
let utilTime = millisecond + expiresTime;
Cookies.set('access_token', result.access_token, { expires: expiresTime });
Cookies.set('utilTime', utilTime);
Cookies.set('refresh_token', result.refresh_token);
Cookies.set('expires_in', result.expires_in);
} else {
//刷新token失败只能跳转到登录页重新登录
localStorage.clear();
Cookies.remove('access_token');
Cookies.remove('utilTime');
Cookies.remove('expires_in');
Cookies.remove('refresh_token');
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath },
});
}
})
.catch(function(err) {
//刷新token失败只能跳转到登录页重新登录
get_sys_logout();
localStorage.clear();
Cookies.remove('access_token');
Cookies.remove('utilTime');
Cookies.remove('expires_in');
Cookies.remove('refresh_token');
console.log(err);
that.openMessage('登录失效');
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath },
});
});
},
};
//http request 拦截器
axios.interceptors.request.use(
config => {
config.data = JSON.stringify(config.data);
init.timer = new Date().getTime();
if (Cookies.get('access_token')) {
if ((parseInt(Cookies.get('utilTime')) - init.timer) / (1000 * 60 * 60) < 0) {
Cookies.remove('access_token');
Cookies.remove('utilTime');
Cookies.remove('expires_in');
Cookies.remove('refresh_token');
get_sys_logout();
localStorage.clear();
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath },
});
}
config.headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${Cookies.get('access_token')}`,
};
} else {
config.headers = {
'Content-Type': 'application/json',
};
}
return config;
},
error => {
Message.error({
message: '加载超时',
});
return Promise.reject(error);
}
);
//响应拦截器即异常处理
axios.interceptors.response.use(
response => {
if (Cookies.get('utilTime')) {
if (!init.isRefresh) {
// 是否是到期前30分钟
if ((parseInt(Cookies.get('utilTime')) - init.timer) / (1000 * 60 * 60) < 0.5) {
init.isRefresh = true;
init.getRefreshToken();
}
}
}
return response;
},
err => {
// debugger
if (err && err.response) {
switch (err.response.status) {
case 400:
console.log('错误请求');
break;
case 401:
//刷新token失败只能跳转到登录页重新登录
get_sys_logout();
localStorage.clear();
Cookies.remove('access_token');
Cookies.remove('expires_in');
Cookies.remove('utilTime');
Cookies.remove('refresh_token');
init.openMessage('登录失效');
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath },
});
break;
case 403:
init.openMessage('拒绝访问');
break;
case 404:
init.openMessage('请求错误,未找到该资源');
break;
case 405:
init.openMessage('请求方法未允许');
break;
case 408:
init.openMessage('请求超时');
break;
case 500:
init.openMessage('服务器端出错');
break;
case 501:
init.openMessage('网络未实现');
break;
case 502:
init.openMessage('网络错误');
break;
case 503:
init.openMessage('服务不可用');
break;
case 504:
init.openMessage('网络超时');
break;
case 505:
init.openMessage('http版本不支持该请求');
break;
default:
init.openMessage(`连接错误${err.response.status}`);
}
} else {
init.openMessage('连接服务器失败');
}
return Promise.resolve(err.response);
}
);
export default axios;
更多推荐
已为社区贡献11条内容
所有评论(0)