Skip to content

前端组件级权限控制的实践

Published:

前言

在后台系统开发中,前端处理权限控制完全是气氛组,最终的权限校验还是要依赖后端的处理。前端的权限控制分为三个主要级别:

权限控制一般有三个级别

组件级别的权限控制

在组件级别,我们的目标是尽量减少权限控制对组件的侵入性。理想情况下,权限控制应该只影响组件的可见度或统一状态,而不是内部逻辑。真正的权限校验仍然需要由后端进行。

示例:根据角色和权限展示不同的组件

假设我们有以下组件按钮:

<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 守卫和角色权限守卫。前端的控制只是辅助工具(完全是气氛组!)。

参考链接