前端权限控制实践:基于 RBAC 的完整落地方案

前端权限控制实践:基于 RBAC 的完整落地方案

关键词:RBAC、动态路由、细粒度权限、React、Ant Design

一、为什么要做前端权限控制

很多同学会问:权限不应该是后端的事吗?后端校验了,前端为什么还要管?

答案是:前端权限不是为了安全(安全永远靠后端),而是为了体验和边界。 一个普通用户点了半天"删除"按钮,提交后被后端一个 403 弹窗打回来,体验极差。更合理的做法是:用户根本没有这个按钮、看不到这个菜单、进不了这个路由。

本文基于我在一个企业级后台(React + UmiJS + Ant Design + DVA)中的真实落地经验,讲清楚一套可复用的 RBAC 前端权限方案。

二、权限模型:RBAC

RBAC(Role-Based Access Control)的核心就三张表:

  • 用户(User) → 绑定一个或多个角色(Role)
  • 角色(Role) → 绑定多个权限点(Permission)
  • 权限点(Permission) → 对应一个具体的操作,如 user:addrole:edit

权限点的设计建议用 资源:操作 的字符串格式,语义清晰,便于后端做注解式鉴权。

js 复制代码
// 登录后后端返回的用户信息(关键字段)
{
  roles: ['admin', 'editor'],
  permissions: ['user:add', 'user:edit', 'role:view', 'dashboard:view']
}

三、四层权限控制

1. 菜单权限

登录后拿到的 permissions 是扁平数组。菜单配置里给每个节点挂一个 permission 字段,渲染前做一次过滤即可:

js 复制代码
// 递归过滤无权限菜单
function filterMenu(menuList, permissions) {
  return menuList.filter(item => {
    if (item.permission && !permissions.includes(item.permission)) return false;
    if (item.children) item.children = filterMenu(item.children, permissions);
    return true;
  });
}

2. 路由权限(最重要)

弱方案:把所有路由写死,进页面再判权限。 强方案:动态路由 。只挂载基础路由(登录、404、403),拿到权限后再 addRoutes 追加受控路由。用户手输一个无权限 URL,直接跳 403,杜绝"能进空白页"的尴尬。

js 复制代码
// 权限守卫(伪代码)
function guard(to, from, next) {
  if (to.meta.permission && !store.permissions.includes(to.meta.permission)) {
    next('/403');
  } else {
    next();
  }
}

3. 按钮级权限

菜单和路由是"粗粒度",按钮是"细粒度"。推荐封装一个 <Auth> 组件或自定义 hook:

jsx 复制代码
function Auth({ permission, children }) {
  const { permissions } = useAuth();
  return permissions.includes(permission) ? children : null;
}

// 使用
<Auth permission="user:add">
  <Button type="primary">新增用户</Button>
</Auth>

4. 接口/数据权限

前端能做的有限,但至少要在请求层统一拦截:无权限接口直接不发起,或根据返回 code 做统一提示,避免重复写 if (res.code === 403)

四、几个踩过的坑

  1. 刷新丢失状态:权限信息存 Vuex/Redux,刷新就没了。要么存 localStorage(注意敏感信息),要么刷新后用 token 重新拉取用户信息。
  2. 动态路由重复添加:路由实例要缓存初始路由,每次重新计算时先重置,否则热更新或重复登录会叠加路由。
  3. 权限语义混乱 :别把"角色"当"权限"用。v-if="role==='admin'" 是反模式,业务一变就改代码。永远判断 permission,角色只作为权限的集合。

五、总结

一套好的前端权限方案 = RBAC 模型 + 动态路由 + 菜单过滤 + 按钮组件 + 请求拦截。它不保证安全,但能让"该看到的人看到,不该看到的人根本不知道存在"。

如果你也在做后台管理,建议从第一天就把权限抽象成 permission 维度,后期几乎零成本扩展。


如果对你有帮助,点赞收藏不迷路。下一篇讲《高并发选课系统的前端架构设计》,关注我持续更新。

相关推荐
八荒启·交互动画1 小时前
Web特效06——WebGL深挖:顶点着色器和片元着色器到底在干什么
前端·网页特效·八荒启-交互动画·八荒启
星空2 小时前
Map<String, String>`Map`是接口,不能直接 new
java·前端·算法
开开心心就好2 小时前
低年级识字练笔顺工具,电脑和安卓端都能用
前端·javascript·网络·安全·scala·erlang·语音识别
杨利杰YJlio2 小时前
ITSK PE 26U5 测试版解读:组件完善、VMD 修复与服务器支持边界
前端·javascript·后端
志尊宝2 小时前
Vue3 零基础每日笔记(021):class 与 style 动态绑定——对象、数组、三元表达式写法汇总
前端·vue.js·笔记·前端框架·html5
夏幻灵2 小时前
Vue / React 列表渲染中的 key:为什么没有 key,Checkbox 可能“对号跑错”?
前端·javascript·vue.js
YWL2 小时前
vue-time-axis-plus进阶:双进度条+跨空白续播+播放指针,打造专业级监控回放体验
前端·javascript·vue·时间轴
mmsx2 小时前
MapLibre 实战 09|Bug 单写着"地图被风刮走了":一个瓦片源工厂,是三个线上事故换来的
android·前端·开源
不羁的木木2 小时前
给鸿蒙 App 增加打开外部网页能力 —— flutter_web_browser 的鸿蒙使用指南
前端·flutter·harmonyos