Vue后台开发实例教程(八)防止token过期,动态刷新token
本实例教程是.net core 系列实例开发教程-权限管理系统前端开发教程,使用PanJiaChen写的Vue后台模板。
本文源码下载地址:http://www.80cxy.com/Blog/ResourceView?arId=202403191532545995NAAqJh
系列教程地址:http://www.80cxy.com/Blog/ArticleView?arId=202403191517574161ay3s5V
服务端生成的token是有过期时间限制的,如30分钟之内有效,超过30分钟就过期了,这时前台需要重新登录,如果用户一直使用着系统,这样用户体验很不好,本文处理方法是前端提交token快过期时,服务端返回一个刷新token的标识,前端收到标识就请求重新获取token。
一、后台代码
后台代码主要判断token是否快过期,如果快过期,返回一个更新token标识。
//获取token过期时间
DateTime expDate = context.HttpContext.User.Claims.Where(x => x.Type == JwtRegisteredClaimNames.Exp)
.Select(x => x.Value).FirstOrDefault().GetTimeSpmpToDate();
//判断jwt是否过期
if ((expDate - DateTime.Now).TotalMinutes < 0)
{
context.Result = new JsonResult(new ResponseContent().Error(ResponseType.TokenExpiration));
return;
}
//前端刷新token标识,离过期5分钟时开始刷新
if ((expDate - DateTime.Now).TotalMinutes < 5 && context.HttpContext.Request.Path != replaceTokenPath)
{
context.HttpContext.Response.Headers.Add("vol_exp", "1");
}
二、前端改造代码
修改src/utils/request.js请求代码:
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
/*********axios二次封装,对外暴露service实例**********/
//创建一个 axios 实例,service就是axios
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
//请求拦截器,请求发出去之前做一些事情
service.interceptors.request.use(
config => {
//config配置对象,包含请求头headers
//判断程序内是否保存token,
if (store.getters.token) {
// let each request carry token
//设置请求携带token,服务器端命名为Authorization
config.headers['Authorization'] = 'Bearer ' + getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
//响应拦截器
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
//成功的回调
response => {
//token刷新标识
let vol_exp = "";
if (response.headers.vol_exp != undefined) {
vol_exp = response.headers.vol_exp;
}
//接收返回数据
const res = response.data
// 响应失败,处理
if (res.code !== 200) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 401: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 401) {
// to re-login
MessageBox.confirm('您已注销,您可以取消以留在此页面上,或重新登录', '确认退出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
//服务端返回token刷新标识
if (vol_exp == "1") {
//刷新token
replaceToken();
}
//响应成功
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
//以下是动态刷新token新增代码
//动态刷新token
function replaceToken() {
ajax({
url: "/api/AdminLogin/RefreshToken",
param: {},
json: true,
success: function (res) {
if (res.code == 200) {
store.dispatch('user/RefreshToken', res.data.token).then(() => {
console.log("token刷新成功")
})
} else {
console.log("Error");
location.reload()
}
},
errror: function (ex) {
console.log("Error");
location.reload()
},
type: "post",
async: false
});
}
function createXHR() {
if (XMLHttpRequest) {
return new XMLHttpRequest();
}
if (ActiveXObject) {
if (typeof arguments.callee.activeXString != "string") {
var versions = [
"MSXML2.XMLHttp.6.0",
"MSXML2.XMLHttp",
"MSXML2.XMLHttp.3.0"
];
for (var i = 0; i < versions.length; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (e) {
console.log(e);
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
}
function ajax(param) {
let httpParam =
Object.assign({
url: '', headers: {},
param: {}, json: true,
success: function () { },
errror: function () { },
type: 'post', async: true
}, param);
httpParam.url = process.env.VUE_APP_BASE_API + "/" + httpParam.url.replace(/\/?/, '');
httpParam.headers['Authorization'] = 'Bearer ' + getToken()
var xhr = createXHR();
xhr.onreadystatechange = function () {
if (xhr.status == 403 || xhr.status == 401) {
redirect(xhr.responseText);
return;
}
//checkResponse(xhr);
if (xhr.readyState == 4 && xhr.status == 200) {
httpParam.success(httpParam.json ? JSON.parse(xhr.responseText) : xhr.responseText);
return;
}
if (xhr.status != 0 && xhr.readyState != 1) {
httpParam.errror(xhr);
}
};
//初始化请求
xhr.open(
httpParam.type,
httpParam.url,
httpParam.async
);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
for (const key in httpParam.headers) {
xhr.setRequestHeader(key, httpParam.headers[key]);
}
let dataStr = '';
for (const key in httpParam.param) {
dataStr += key + "=" + httpParam.param[key];
}
try {
xhr.send(dataStr);
} catch (error) {
toLogin();
}
}
ajax.post = function (url, param, success, errror) {
ajax({ url: url, param: param, success: success, error: errror, type: 'post' })
}
ajax.get = function (url, param, success, errror) {
ajax({ url: url, param: param, success: success, error: errror, type: 'get' })
}
function toLogin() {
this.$router.push({ path: '/login', params: { r: Math.random() } });
}
export default service
猜您可能还喜欢
- CERT_HAS_EXPIRED错误如何解决(2964)
- Js异步async、await关键字详细介绍(lambda表达式中使用async和await关键字)(2600)
- Vue 2.x + Element后台模板开发教程(三)后台首页模板设计(1294)
- vuex中 this.$store.dispatch() 与 this.$store.commit()方法的区别(1269)
- Error: Cannot find module ‘chokidar‘ 解决方法(1258)
- Vue后台开发实例教程(二)Title修改及左侧菜单修改(1147)
- Vue 2.x + Element后台模板开发教程(一)(1120)
- vuejs中如何使用axios调用后台接口(1115)
- vue.js初探(一)vue.js全家桶介绍(914)
- vue.js初探(三)vue页面结构(908)
评论列表
发表评论
文章分类
文章归档
- 2025年3月 (1)
- 2024年6月 (2)
- 2024年5月 (2)
- 2024年4月 (4)
- 2024年3月 (30)
- 2024年1月 (4)
- 2023年12月 (2)
- 2023年11月 (4)
- 2023年10月 (4)
- 2023年9月 (6)
- 2023年3月 (2)
- 2023年2月 (1)
- 2023年1月 (1)
- 2022年12月 (1)
- 2022年9月 (21)
- 2022年8月 (10)
- 2022年7月 (3)
- 2022年4月 (1)
- 2022年3月 (13)
- 2021年8月 (1)
- 2021年3月 (1)
- 2020年12月 (42)
- 2020年11月 (7)
- 2020年10月 (5)
- 2020年8月 (1)
- 2020年6月 (1)
- 2020年3月 (2)
- 2019年12月 (8)
- 2019年11月 (3)
- 2019年9月 (1)
- 2019年4月 (1)
- 2019年3月 (6)
- 2019年2月 (1)
- 2018年7月 (7)
阅读排行
- 1.asp.net mvc内微信pc端、H5、JsApi支付方式总结(5876)
- 2.Windows 10休眠文件更改存储位置(3825)
- 3.各大搜索网站网站收录提交入口地址(3478)
- 4.ECharts仪表盘实例及参数使用详解(3431)
- 5.windows 10安装myeclipse 10破解补丁cracker.jar、run.bat闪退解决办法(3422)
- 6.HTML5 WebSocket与C#建立Socket连接实现代码(3179)
- 7.华为鸿蒙系统清除微信浏览器缓存方法(3171)
- 8.CERT_HAS_EXPIRED错误如何解决(2964)
- 9.Js异步async、await关键字详细介绍(lambda表达式中使用async和await关键字)(2600)
- 10.HBuilder编辑器格式化代码(2393)
