关于解决token过期失效问题「建议收藏」

2022-10-01 16:26:19 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

关于解决token过期失效问题,用户对token无感知(实现免登陆)
  • 一、先认识下token
  • 二、整体思路
  • 三、实现步骤
    • 1.理清各个文件作用
    • 2.路由导航守卫
    • 3.封装localStorage方法
    • 4.vuex
    • 5.封装axios 实现请求拦截器和响应拦截器(重点部分)
  • 四、小结

一、先认识下token
二、整体思路
三、实现步骤
1.理清各个文件作用
2.路由导航守卫

设置用户有无token访问主页,并且登录成功回到目标页

代码语言:javascript复制
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store/index.js'
Vue.use(VueRouter)
const router = new VueRouter({ 

routes
})
// 路由导航守卫
router.beforeEach((to, from, next) => { 

if (to.path.startsWith('/user')) { 

// 判断token
if (store.state.tokenInfo.token) { 

next()
} else { 

next({ 

path: '/login',
query: { 

// 登录成功回到目标页
backto: to.fullPath // fullPath 会拿到路由后面的查询字符串
}
})
}
} else { 

next()
}
})
export default router
3.封装localStorage方法

目的在vuex中调用

代码语言:javascript复制
/ 封装模块 使用localStorage实现持久化 只是进行保存
// 从localStorage中取出一项数据 名字叫name
export const getItem = name => { 

return JSON.parse(localStorage.getItem(name))
}
// 向localStorage中设置一项数据 名字为name里面设置值为obj
export const setItem = (name, obj) => { 

localStorage.setItem(name, JSON.stringify(obj))
}
// 删除
export const removeitem = name => { 

localStorage.removeItem(name)
}
4.vuex
代码语言:javascript复制
import Vue from 'vue'
import Vuex from 'vuex'
import { 
 setItem, getItem } from '@/utils/storage.js'
Vue.use(Vuex)
export default new Vuex.Store({ 

state: { 

// 保存公共数据
tokenInfo: getItem('tokenInfo') || { 
}
},
mutations: { 

mSetTokenInfo (state, tokenObj) { 

state.tokenInfo = tokenObj
// 因为刷新会丢失所以进行持久化 调用storage方法
setItem('tokenInfo', tokenObj)
}
},
// -------------------此次重点---------------------------------------------------------
// 只跟新token 不跟新响应拦截器里面的refreshToken
mUpdateToken (state, newToken) { 

state.tokenInfo.token = newToken
setItem('tokenInfo', state.tokenInfo)
},
actions: { 

},
modules: { 

}
})
5.封装axios 实现请求拦截器和响应拦截器(重点部分)

关于axios拦截器 可参考官方文档 (点我)axios拦截器官方跳转链接

代码语言:javascript复制
/* 对axios进行二次封装 请求拦截器增加token 响应拦截器处理大数据 */
import store from '@/store/index.js'
import axios from 'axios'
import JSONbig from 'json-bigint' // 引入大数字包
import router from '@/router/index.js'
/* 以前写法: axios.defaults.baseURL = 'XXX' 自定义写法:const xxx = axios.create({}) 一个项目中可能有不同的基地址 就要用自定义写法设置不同的基地址 */
const instance = axios.create({ 

baseURL: 'http://ttapi.research.itcast.cn',
transformResponse: [function (data) { 

if (data === '') { 

return false
}
try { 

// 如果没有遇到错误,就返回 JSONbig处理之后的数据
return JSONbig.parse(data)
} catch (err) { 

console.log('JSONbig转换出错', err)
return data
}
}]
})
// 在instance上添加请求拦截器 补充请求头token信息
instance.interceptors.request.use(function (config) { 

// 从vuex中取出token
const token = store.state.tokenInfo.token
// 如果有token则 添加到headers中
if (token) { 

config.headers.Authorization = `Bearer ${ 
token}`
}
return config
}, function (error) { 

return Promise.reject(error)
})
//------------------------这里处理token过期--------------------------------------------
// 添加响应拦截器 处理401 token过期
instance.interceptors.response.use(function (response) { 

return response
}, async function (error) { 

// 如果是401错误 则做以下错误
if (error.response.status === 401) { 

// 从vuex中取出token
const refreshToken = store.state.tokenInfo.token
// 是否有refreshToken
if (refreshToken) { 

// 用refresh_token 重发请求 再次取回一个有效期的
try { 

// 注意这里重新发请求要用axios 不能用封装的instance url地址是根据接口文档写的
const { 
 data: res } = await axios({ 

method: 'PUT',
url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',
headers: { 

Authorization: `Bearer ${ 
refreshToken}`
}
})
// 定义赋值新的token
const newToken = res.data.token
// 跟新vuex
store.commit('mUpdateToken', newToken)
// 再发请求
return instance(error.config)
} catch { 
  // 如果没有拿到新的token 
// 回登录页
router.push({ 

path: '/login',
query: { 

// currentRoute表示当前路由对象
backto: router.currentRoute.fullPath
}
})
}
} else { 
   // 如果没有refreshToken
router.push({ 

path: '/login',
query: { 

backto: router.currentRoute.fullPath
}
})
}
} else { 
  // 如果不是401错误
return Promise.reject(error)
}
})
export default instance
四、小结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/194603.html原文链接:https://javaforall.cn

0 人点赞