1、token 在诸多组件中可能用得到,建议用vuex管理数据,包裹同步mutations 和异步 actions,整个模式就变成vuex到actions,业务组件中直接触发actions函数
2、 vuex存储数据的方式:基于内存(特点:存取速度特别快,vuex和vue经过绑定,使用方便,快,刷新浏览器会丢失)
3、 cookie和localStorage 本地存储:基于磁盘(特点:存取速度稍慢,持久化的功效,浏览器刷新不会丢失)
4、token有时效,可能失效,故使用vuex配合cookie,初始化时优先从本地取,取到就用,取不到再按格式要求初始化成空串
1、本地存储
state: {
token: localStorage.getItem('token') || '',
},
mutations: {
setToken(state, newToken) {
// token 存储到本地local storage
localStorage.setItem('token', newToken)
},
// 清除token,用户信息
removeInfoToken(state) {
localStorage.removeItem('token')
}
}
2、vuex 管理 token
state:{
token:''
}
mutations:{
setToken(state, newToken) {
// token 存储在vuex
state.token = newToken
},
//移除token
removeInfo(state) {
state.token = ''
}
}
actions:{
async updateToken(context, data) {
//调用登录接口
const res = await login(data)
// 调用mutation修改数据
context.commit('setToken', res)
}
}
//登录页面 登录事件中进行触发
// 加await是因为dispatch函数执行的结果同样是一个promise,可以通过awiat模拟同步
//触发action函数updateToken
await this.$store.dispatch('user/updateToken', this.loginForm)
3、cookie
封装cookie
https://github.com/js-cookie/js-cookie
import Cookies from 'js-cookie'
const TokenKey = 'token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
import { getToken, setToken, removeToken } from '@/utils/auth'
state: {
token: getToken() || '',
},
mutations: {
setToken(state, newToken) {
setToken(newToken)
},
// 清除token
removeInfoToken(state) {
// 清除本地
removeToken()
}
}
js-cookie
安装: nom i js-cookie
导包:import Cookies from 'js-cookie'
设置cookie :Cookies.set('default_unit_second', state.profile.id)
4、借助第三方插件 vuex-persistedstate
Vuex数据状态持久化-vuex-persistedstate - 简书 (jianshu.com)
1、安装 npm i vuex-persistedstate
2、引入
3、配置
5、请求拦截器
让每一个请求的header中都拥有token,后端要求的固定标识 Bearer token
// 请求拦截器
service.interceptors.request.use(
// 注入token
config => {
// console.log(config)
// 获取token
const token = store.state.user.token
// const token = store.state.token
// console.log(store)
if (token) {
// 注入到request 的headers
config.headers['Authorization'] = `Bearer ${token}`
// console.log(config.headers)
}
return config
},
error => {
return Promise.reject(error)
}
)
6、token失效,在响应拦截器中设置
token失效之后,后端会配合返回一个401状态码,前端可以把这个状态码作为判断条件
service.interceptors.response.use(
// response => response.data,
response => {
const { data, message, success } = response.data
if (success) {
// 接口成功,返回数据
return data
} else {
// 提示错误信息
Message.warning(message)
return Promise.reject(message)
}
},
error => {
// console.dir(error)
if (error.response && error.response.status && error.response.status === 401) {
store.commit('user/removeInfoToken')
// 在哪个路由下发生的失效 将来登录之后跳回来
router.push(`/login?redirect=${router.currentRoute.fullPath}`)
}
return Promise.reject(error)
}
)