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错误如何解决(2245)
- Js异步async、await关键字详细介绍(lambda表达式中使用async和await关键字)(2188)
- Vue 2.x + Element后台模板开发教程(三)后台首页模板设计(1213)
- vuex中 this.$store.dispatch() 与 this.$store.commit()方法的区别(1190)
- vuejs中如何使用axios调用后台接口(1025)
- Vue 2.x + Element后台模板开发教程(一)(1020)
- Error: Cannot find module ‘chokidar‘ 解决方法(1009)
- Vue后台开发实例教程(二)Title修改及左侧菜单修改(901)
- vue.js初探(一)vue.js全家桶介绍(825)
- vue.js初探(三)vue页面结构(820)
评论列表
发表评论
文章分类
文章归档
- 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支付方式总结(5702)
- 2.各大搜索网站网站收录提交入口地址(3201)
- 3.Windows 10休眠文件更改存储位置(3163)
- 4.ECharts仪表盘实例及参数使用详解(3095)
- 5.windows 10安装myeclipse 10破解补丁cracker.jar、run.bat闪退解决办法(2991)
- 6.HTML5 WebSocket与C#建立Socket连接实现代码(2866)
- 7.华为鸿蒙系统清除微信浏览器缓存方法(2779)
- 8.CERT_HAS_EXPIRED错误如何解决(2245)
- 9.Js异步async、await关键字详细介绍(lambda表达式中使用async和await关键字)(2188)
- 10.HBuilder编辑器格式化代码(2118)