我们平时开发项目中,并不是所有的路由都可以直接访问,有些路由需要登录之后才可以查看,这里就需要在跳转时进行一个判断,如果已经登录则直接跳转,否则跳转到登录页。通过全局导航守卫实现,即router.beforeEach。
这并没有结束,本地可能存在登录信息,但可能出现信息过期的可能。这样进行数据请求时应该跳转到登录页,这里就需要在每次的数据请求时增加一个判断。
axios拦截器在每一次数据请求前和请求后进行相应的处理。下面介绍axios如何使用:
1、安装
npm install axios
2、main.js引入
import axios from 'axios'
Vue.prototype.$axios = axios
3、在main.js使用
// 添加请求拦截器
axios.interceptors.request.use(
config => {
// 在发送请求之前做些什么
console.log('在发送请求之前触发')//示例代码
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
console.log('响应数据成功触发')//示例代码
return response;//返回相应的数据
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
拦截器的简单实用如上,每一次axios请求都会先后触发以上两个拦截器。具体应用后面叙述
前面说到了每次路由跳转前都要进行判断是有需要登录权限。那么我们在定义路由的时候需要添加一个字段gorouter,用于判断。
const routes = [
{
path: '/login',
name: 'login',
component: Login,
},
{
path: '/',
name: 'home',
component: Home,
meta:{
app:true,
}
},
{
path: '/about',
name: 'about',
component: About,
meta:{
app:true,
gorouter:true,//需要权限
}
},
{
path: '/news',
name: 'news',
component: News,
meta:{
gorouter:true,//需要权限
}
},
]
const router = new VueRouter({
// mode: 'hash',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to,from,next) => {
if(to.meta.gorouter){ //判断该路由是否需要权限
if(store.state.token){ //判断store是否有登录信息,存储在token字段
next()
}else{
next({
path:'/login',
query:{redirect:to.fullPath} //将该路由path传入login页面,登陆成功后跳转到该页面
})
}
}else{
next()
}
})
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航
说明:
每次路由跳转前都会执行router.beforeEach,首先判断路由中的字段gorouter,如果不存在则不需要登录则直接跳转。对需要跳转的路由再次检查,在vuex中是否存在登录信息store.state.token,如没有则将准备进入的路由to.fullPath作为query的参数传入Login,登录成功后跳转到该页面。
(store官方传送门)
前言:
一个完整的token验证大致分为以下几步
1、前端用户登录成功后,后端发送一个token信息(一般包含过期时间、uid等信息)反馈给前端
2、前端得到token并存入vuex,本地存储(localStroge)
3、用户进行路由跳转时,判断该路由是否需要登录权限,如果需要,则检查vuex是否含有token。
4、每一次数据请求都触发拦截器,在请求头加入token,交给后端判断。
5、后端验证请求是否含有token信息,或者token时是否过期,并返回相应的错误状态码(比如401、404等)
6、前端得到错误代码进行相应处理,如果成功则更新token
1、请求拦截
// 添加请求拦截器
axios.interceptors.request.use(
config => {
if(store.state.token){//添加token信息在请求中
config.headers.Authorization = store.state.token
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
这样每一次请求都会加上token信息交给后端判断
下面我们测试一下是否添加成功
模拟发送一个数据请求,给一个测试的token信息
axios.interceptors.request.use(
config => {
config.headers.Authorization = 'sfrbafhwtb'
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
可以看到,测试的token信息成功添加到请求头中
2、响应拦截
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
if(response.status === 200){ //成功状态码200
store.state.token = response.data.data.body.token //更新token
return response; //返回响应的数据
}else{
return Promise.reject(response)
}
}, function (error) {
// 对响应错误做点什么
if(error.response.status){
switch(error.response.status){
//未登录,跳转到登录页并携带当前页路径,登录成功后跳转
case 401:
router.replace({
path:'/login',
query:{redirect:router.currentRoute.fullPath}
})
//token过期,对用户提示然后清除本地token再跳转
case 403:
Toast({
message:'登陆过期',
duration:1000,
})
localStorage.removeItem('token')
store.commit('token')
setTimeout(() => {
router.replace({
path:'/login',
query:{redirect:router.currentRoute.fullPath}
})
},1000)
//请求不存在
case 404:
Toast({
message:'请求不存在',
duration:1000,
})
break
//其他错误,提示错误
default:
Toast({
message:error.response.data.message,
duration:1000,
})
}
}
return Promise.reject(error);
});
结语:
以上就是一个基础版的拦截器token验证,如有错误欢迎大家指正。