作用:部分页面需要权限才能访问,Vue拦截器能在用户访问这些页面前进行拦截并验证,然后判断用户是否有权限访问该页面。
1、定制一个store对token进行存储(扩充store文件夹下的index.js)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
token: ''
},
mutations: {
set_token(state,token){
state.token = token
sessionStorage.token = token
},
del_token(state){
state.token = ''
sessionStorage.removeItem('token')
}
},
actions: {
},
modules: {
}
})
export default store
2、前端定制拦截器
安装axios, npm install axios --save
为了方便管理,在router文件夹下创建http.js,这里面定制好拦截器
import axios from 'axios';
import router from './index';
import store from "../store";
// axios 配置
axios.defaults.timeout = 8000;
axios.defaults.baseURL = 'http://localhost:8080';
// http request 拦截器
axios.interceptors.request.use(
config => {
if (store.state.token) { //判断token是否存在
console.log("放入token")
config.headers.Authorization = store.state.token; //将token设置成请求头
}
return config;
},
err => {
return Promise.reject(err);
}
);
// http response 拦截器
axios.interceptors.response.use(
response => {
if (response.data里的属性符合某个条件) {
router.replace('/');
console.log("token过期");
}
return response;
},
error => {
return Promise.reject(error);
}
);
export default axios;
3、设置导航守卫
在router文件夹下的index.js里设置导航守卫,配合拦截器进行检验token
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {// 判断该路由是否需要登录权限
if (store.state.token) { // 获取当前的token是否存在
console.log("token存在");
next();
} else {
console.log("token不存在");
next({
path: '/login', // 将跳转的路由path作为参数,登录成功后跳转到该路由
query: {redirect: to.path} //添加参数,方便登录后重定向到当前网页
})
}
}
else { // 如果不需要权限校验,直接进入路由界面
next();
}
});
to: Route
: 即将要进入的目标 [路由对象]from: Route
: 当前导航正要离开的路由next: Function
: 一定要调用该方法来 resolve 这个钩子。执行效果依赖next
方法的调用参数
具体参数含义可以参照Vue官网:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB
4、在需要拦截的路由添加meta信息
{
path: '/edit',
name: '文本编辑框',
component: Edit,
show:false,
meta: {
requiresAuth: true //需要验证
}
}
5、登录后存储token
_this.$store.commit('set_token',resp.data.token)
这里展示一个Demo
methods: {
submitForm(formName) {
const _this = this
this.$refs[formName].validate((valid) => {
if (valid) {
axios.post('http://localhost:8081/user/login',this.ruleForm).then(function (resp) {
_this.$store.commit('set_token',resp.data.token)
// console.log("这是token"+resp.data.token)
// console.log(store.state.token)
if(store.state.token){
if(_this.$route.query.redirect !=null)
_this.$router.push(_this.$route.query.redirect)
else _this.$router.push('/UserAdmin/BookManage')
}
else {
_this.$alert('账号或者密码错误', '消息', {
confirmButtonText: '确定',
callback: action => {
// _this.$router.push('/BookManage') 本来就在这个页面,这样跳转不会刷新
window.location.reload() //动态刷新当前页面
}
})
// _this.$router.push('/login')
}
})
} else {
_this.$alert('用户账号或密码错误', '消息', {
confirmButtonText: '确定',
callback: action => {
_this.$router.push('/login')
}
});
}
});
}
6、token的生成我采用Spring Boot + JWT,可以参考我的另一篇文章《SpringBoot + JWT 定制 API权限》
https://blog.csdn.net/LiuZihao97/article/details/105670948