【vue】通过路由拦截无权限访问的权限页面
前景:一个系统平台,针对不同用户登录做了一个权限功能,首先展示的菜单,事先在route.js中配置好,根据后台返回的菜单名称,按需展示对应菜单。但是当时忘记做一个判断,若一个用户已经登录,虽然菜单未展示比如权限管理页面,但对方知道权限管理页面地址,在地址栏中直接输入地址,可直接访问。因为在路由中没有做拦截判断。下面上代码:router文件夹中有两个文件,一个是index.js,一个是route..
·
前景:一个系统平台,针对不同用户登录做了一个权限功能,首先展示的菜单,事先在route.js中配置好,根据后台返回的菜单名称,按需展示对应菜单。但是当时忘记做一个判断,若一个用户已经登录,虽然菜单未展示比如权限管理页面,但对方知道权限管理页面地址,在地址栏中直接输入地址,可直接访问。因为在路由中没有做拦截判断。
下面上代码:
router文件夹中有两个文件,一个是index.js,一个是route.js
router/route.js
import basic from "@/pages/basic/basic" // 这是一个公共页面,每个页面都用的到
export const routes = [
{
name: 'home',
title: 'home',
path: '/home',
component: basic,
redirect: '/home/home',
children: [
{
name: 'home',
title: 'home',
path: '/home/home',
component: home
}
]
},
{
name: 'menu',
title: 'menu',
path: '/menu',
component: basic,
redirect: '/menu/menu1',
children: [
{
name: 'menu1',
title: 'menu1',
path: '/menu/menu1',
meta: { requiresAuth: true }, // 若是需要校验权限的页面,需在该页面配置此属性
component: menu1
},
{
name: 'menu2',
title: 'menu2',
path: '/menu/menu2',
meta: { requiresAuth: true },
component: menu2
},
{
name: 'menu3',
title: 'menu3',
path: '/menu/menu3',
component: menu3
}
]
},
{
name: 'system',
title: 'system',
path: '/system',
component: basic,
redirect: '/system/role',
children: [
{
name: 'role',
title: 'role',
path: '/system/role',
meta: { requiresAuth: true },
component: role
}
]
}
]
exportconst login = {
name: 'login',
title: 'login',
path: '/',
component: login,
}
export const routers = [
...routes,
login
]
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import { store } from '@/store/index'
import { Message } from "element-ui" // 弹框组件
import Cookies from 'js-cookie'
import { routers } from '@/router/route';
Vue.use(Router)
const router = new Router({
mode: 'history',
routes: routers
})
router.beforeEach((to, from, next) => {
if (Cookies.get('userNo')) {// 判断是否缓存中有userNo,这是一个工号,没有跳回登录页
if (to.matched.some(res => res.meta.requiresAuth)){
// 此处是根据我在路由中添加的meta.requiresAuth属性,
// 若访问的页面中有我这项属性,那么当用户直接访问该页面时,会进入此项判断。
// 下面我要在这里判断,用户访问的to.path,跟我菜单中的path是否一致,
// 若一致,那么该登录者可以访问此页面,
// 若不一致,将跳出登录页,或提示用户无权限访问该页面
let menuListStatus = store.state.menuListStatus;// 接口返回可以访问的菜单,存储在vuex中
let menuList = store.state.menuList;// 根据返回的菜单跟我路由中配置好的router数组做处理,把不需要展示的菜单过滤掉,存储在vuex中
if (menuListStatus && menuListStatus.length != 0) {
if (menuList && menuList.length != 0) {
let isMenu = deepQuery(menuList,to.path);
if (isMenu) {// 若存在,继续访问
next();
} else {
Message({
message: '无权限访问',
type: "warning"
});
next('/');
}
} else {
next();
}
} else {
next();
}
} else {// 若没上面的判断,说明是访客组就可以访问的页面
next();
}
} else {
next({ path: '/'})
}
})
// 查找菜单数组中path是否存在
function deepQuery(tree,path) {
var isGet = false;
var retNode = null;
function deepSearch(tree,path){
for(var i = 0; i<tree.length; i++) {
if(tree[i].children && tree[i].children.length>0) {
deepSearch(tree[i].children,path);
}
if(path === tree[i].path || isGet) {
isGet||(retNode = tree[i]);
isGet = true;
break;
}
}
}
deepSearch(tree,path);
return retNode;
}
store/index.js文件如下
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
var store = new Vuex.Store({
state: {
menuListStatus: [],
menuList: []
},
mutations: {
saveMenu (state,data) {
state.menuListStatus = data;
},
saveMenuList (state,data) {
state.menuList= data;
}
}
})
我菜单请求回来的数据:
import _ from 'lodash' //这个自行科普吧
import { store } from '@/store/index'
import { routers } from '@/router/route';
// 后台返回只有菜单名字,所以要处理一下
var menuList = [
{
id: 1,
title: 'home'
},
{
id: 2,
title: 'menu1'
},
{
id: 3,
title: 'menu2'
},
{
id: 4,
title: 'menu3'
}
]
// 把拿到的菜单存储在vuex中
store.commit('saveMenulistStatus',menuList);
// 下面要把拿到的菜单跟router中的数组做处理
function accessRecursive(arr) {// 处理拿到的菜单与路由处理
letflag = false
let jsonArr = menuList;
for(var I = 0; I < arr.length; I++){
var item = arr[I]
if (item.children) {
item.allow = accessRecursive(item.children)
}
if (item.allow || jsonArr.some(ele => ele.title === item.title)) {
item.allow = true
}
flag = flag || item.allow
if (!item.allow) {
arr.splice(I, 1)
I--
}
}
return flag
},
let routeArr =_.cloneDeep(routers);
let list = [];
list = accessRecursive(routeArr);
// 处理后的菜单放入vuex中
store.commit('saveMenuList',list)
综上所述,根据后台返回给我的菜单中没有role这个页面,所以该用户登录之后,若在地址栏中输入/system/role,是无法访问的。
更多推荐
已为社区贡献6条内容
所有评论(0)