前言
在后台系统开发中,前端处理权限控制完全是气氛组,最终的权限校验还是要依赖后端的处理。前端的权限控制分为三个主要级别:
权限控制一般有三个级别
- 页面级:通过路由守卫和动态路由来限制访问,用户没有权限无法看到这个菜单或页面,细粒度较低。
- 组件级:根据用户角色和权限显示不同的组件或内容。例如,管理员可以看到更多的数据,而普通用户只能看到基本信息。这种方法具有一定的侵入性。
- 代码级:精确到函数调用权限控制,虽然不常见,但某些场景下可能会用到。
组件级别的权限控制
在组件级别,我们的目标是尽量减少权限控制对组件的侵入性。理想情况下,权限控制应该只影响组件的可见度或统一状态,而不是内部逻辑。真正的权限校验仍然需要由后端进行。
示例:根据角色和权限展示不同的组件
假设我们有以下组件按钮:
<div class="btn-container">
<a-button type="primary">新增用户</a-button>
<a-button type="primary">查看用户</a-button>
<a-button type="primary">修改用户</a-button>
<a-button type="primary" danger>删除用户</a-button>
<a-button type="primary" danger>禁用用户</a-button>
</div>
如果权限仅影响组件的可见度,我们可以使用权限组件或自定义指令来包裹这些操作按钮。
权限组件
我们可以创建一个 Authority
组件来控制按钮的显示:
<Authority permissions="sys:user:add">
<a-button type="primary">新增用户</a-button>
</Authority>
单个权限
只有当用户拥有 sys:user:add
权限时,按钮才会显示。
如果用户没有某个权限,那么就不会显示出来。
可以看到,添加按钮没了。因为 Visitor 角色没有 sys:user:add
权限。
多个权限
如果某个按钮需要多个权限才能显示:
<Authority :permission="['sys:user:view', 'sys:user:update']">
<a-button type="primary" danger>禁用用户</a-button>
</Authority>
我们之所以能够减少权限对组件的侵入性是因为权限关联到了组件的统一状态,都是可见和不可见的区别。
权限作用域
如果你希望组件能够自行处理权限控制,可以使用 Authority
组件的作用域插槽:
<Authority>
<template #default="{ userPermissions }">
<a-button :disabled="userPermissions.includes('sys:user:add')">新增用户</a-button>
</template>
</Authority>
Authority 组件
Authority
组件的实现如下,接收权限 props
并根据权限计算属性控制插槽内容的显示:
<template>
<slot v-if="showSlot" :userPermissions="permissions">
<!-- 按钮 -->
</slot>
</template>
<script setup lang="ts">
interface Props {
permission: string[];
}
const props = withDefault(defineProps<Props>(), {
permission: () => [],
});
// 使用 pinia 来存放后端返回的权限
const { permissions } = useAuth();
const showSlot = computed(() => {
// 没有传入权限,直接显示
if (!props.permission) return true;
if (!permissions) {
return false;
}
// 如果插槽按钮需要多个权限才能显示
if (Array.isArray(props.permission)) {
// 判断父组件传过来的 permission 是不是当前用户权限拥有的
return props.permission.every(p => permissions.include(p));
} else {
// 如果父组件传过来单个权限
return permissions.value.includes(props.permission);
}
});
</script>
总结
尽管前端的权限控制可以提升用户体验,但真正的安全保障仍然需要依靠后端来进行权限验证如使用 Token 守卫和角色权限守卫。前端的控制只是辅助工具(完全是气氛组!)。