权限控制是中后台系统常见的需求,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源。
以下demo的做法是将菜单和路由结合起来,并接受后端传回的用户权限信息,通过对路由管理来做权限的校验,对于没有通过权限校验的用户进行提示或者跳转到相应的页面。
获取当前用户的权限:
export function getCurrentAuth() {
// 接口请求数据
return [“admin”]; // 模拟后台返回的用户权限
}
验证路由定义的权限是否在当前用户权限中:
export function check(auth) {
const current = getCurrentAuth();
return current.some(item => auth.includes(item));
}
判断用户是否登录:
export function isLogin() {
const current = getCurrentAuth();
return current $$ current !== ‘guest’;
}
在路由守卫中做判断,根据路由设定的权限,判断用户是否有访问权限:
Import Vue from “vue”
import findLast form “lodash/findLast ”
import NProgress form “nprogress ” // 页面跳转进度条组件
import Layout from '@/layout'
import Router form “vue-router ”
Import {check, isLogin} from “/utils/auth”
Vue.use(Router )
cost router = new Router({
mode: “history”,
routes: [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path*',
component: () => import('@/views/redirect/index')
}
]
},
{ // 登录页面路由
path: “/login”,
hidden: true
component: () => import('@/views/login/index')
},
{
...
},
});
router.beforeEach((to, from, next) => {
If (to.path !== from.path) {
NProgress.start();
}
const record = findLast(to.matched, record => record.meta.authority) // 获取路由定义的权限信息
If (record && !check(record.meta.authority) ) { // 验证权限是否符合
If(!isLogin() && to.path !== “/user/login”){ // 判断是否登录
next({
path: “/user/login”
})
} else if (to.path !== “/403”) {
next({
path: “/403”
})
}
NProgress.done(); // 结束进度条
}
next();
});
router.afterEach(() {
NProgress.done();
});
export default router
修改菜单展示内容,只展示用户拥有权限的菜单:
import {check} from “/utils/auth”
methods:{
getUserMenu(routes = [], parentKeys = [], selectedKey) {
const menuData = [];
for (let item of routes) {
If (item.meta.authority && !check(item.meta.authority )) { // 过滤路由
Break;
}
...
}
}
}
页面内部的权限校验方式,编写权限检验组件Authorized:
<script>
import {check} from “@/utils/auth”;
Export default {
functional: true;
props: {
authority: {
type: Array,
required: true
}
},
render:(h, context) {
const {props, scopedSlots} = context;
Retrun check(props.authority) ? scopedSlots.default() : null;
}
}
</script>
并注册该组件为全局组件Vue.component(“Author”,Author)
页面中使用方法:
<Author :authority: "['admin', 'user']">
<button type="warning">编辑</button>
</Author>