接上篇前端权限设计实现-按钮级,这篇写下在路由级别进行权限控制,毕竟按钮只是隐藏了入口,通过修改浏览器的路由地址,或许是可以进入受权限控制的页面。
既然我们想到了按钮级的权限无法阻拦修改浏览器的路由地址去进入到相关页面,那就只能对路由进行控制,Vue 提供的有 路由守卫 的相关方法,可以直接去监听、控制路由变化。
同时对于路由表,应当有相应的设置,以便分析哪些路由需要进行权限控制。
### 路由表设计
路由表结构如下:
const routes = [
{
path: '/user',
component: BasicLayout,
children: [
{
path: '/',
redirect: '/user/login'
},
{
path: '/user/login',
name: 'login',
component: () => import("@views/User/Login")
},
]
},
{
path: '/',
component: BasicLayout,
meta: {
anthority:['user','admin']
}
children: [
{
path: '/',
redirect: '/dashboard/analysis'
},
// dashboard
{
path:'/dashboard',
name: 'dashboard',
component: {render:h=>h('router-view')},
children:[
{
path: "/dashboard/analysis",
name: 'analysis',
component:()=>import("@views/Dashboard/Analysis")
}
]
},
// form
{
path: 'form',
name: 'form',
meta:{
authority: ["admin"]
}
component: {render:h=>h('router-view')},
children: [
{
path: "/form/basic-form",
name: 'basicform',
component:()=>import("@views/Form/BasicForm")
},
...
]
}
]
}
]
其中对登录后的页面,限制 user,admin
访问,Form 表单限制 admin
访问。
路由守卫
import findLast from "lodash/findLast";
import {check} from './utils/auth.js';
router.beforEach({to,from,next}=>{
// findLast: 找到临近当前对象的authority
const record = findLast(to.matched, record =>record.meta.authority)
if(record && !check(record.meta.authority)){
if(!isLogin() && to.path !== '/user/login'){
next({
path:"/uset/login"
})
}else if(to.path !=="403"){
next({
path:"/403"
})
}
}
next();
})
思路
通过在路由元信息中的 meta 上添加 authority 字段,进行权限设置,在路由守卫中,查询路由记录最近节点所设置的 authority 是否可以通过 check 函数(上篇有写)的检查,如果check不通过的话,进行路由拦截,同时对路由判断,避免堆栈溢出。
其中 to.matched
可以进行调试或打印出来,观察具体信息。
最后
前端的权限控制只是隐藏相关内容,如果直接调用接口去访问服务器的话,前端是阻拦不了的,因此权限控制应当是前端和服务端共同控制,前端控制展示,服务端控制行为。
下篇写 lodash 和 函数式编程