前端权限管理
权限管理是前端工程化中保障系统安全的核心环节。前端权限通常包括路由权限、按钮权限和数据权限三个层次,配合后端 RBAC(基于角色的访问控制)模型,构建完整的权限体系。
前端权限体系
路由权限
控制用户能访问哪些页面。未授权的路由应重定向到 403 页面或登录页。
实现方案:
- 动态路由:根据角色动态添加路由表
- 路由守卫:通过导航守卫拦截未授权访问
按钮权限
控制用户能看到哪些操作按钮。例如:编辑者可以看到「新增文章」按钮,访客则看不到。
实现方案:
- 指令权限:
v-permission="'user.create'"自定义指令控制元素显示 - 组件级权限:通过
if条件判断hasPermission()结果
数据权限
控制用户能看到哪些数据范围。例如:普通用户只能看到自己的数据,管理员可以看到全部。
数据权限主要由后端控制,前端配合展示过滤条件。
CASL 权限库实战
CASL 是一个通用权限管理库,支持 isomorphic 前后端同构:
javascript
import { defineAbility } from '@casl/ability';
// 定义权限
const ability = defineAbility((can, cannot) => {
can('read', 'Article');
can('update', 'Article', { authorId: currentUser.id });
cannot('delete', 'Article');
});
// 检查权限
ability.can('read', 'Article'); // true
ability.can('delete', 'Article'); // falseCASL 的特点:
- 框架无关,可直接在 React/Vue/Angular 中使用
- 支持基于条件的细粒度权限检查
- 前端可缓存权限规则,避免每次操作都请求后端
RBAC 模型设计
用户 ──→ 角色 ──→ 权限RBAC(Role-Based Access Control)通过角色作为中间层,将权限分配给角色,再将角色赋予用户。
角色设计示例
| 角色 | 描述 | 典型权限 |
|---|---|---|
| 管理员 | 系统完全控制 | 所有模块的增删改查 |
| 编辑者 | 内容维护 | 文章增改、数据查看 |
| 访客 | 只读访问 | 仅查看公开内容 |
权限数据结构
json
{
"role": "editor",
"permissions": {
"dashboard": { "view": true },
"content": { "view": true, "create": true, "edit": true },
"users": { "view": true },
"reports": { "view": true, "export": true }
}
}动态路由实现
以 Vue Router 为例,根据角色动态注册路由:
javascript
// 根据角色权限生成可访问路由
function generateRoutes(permissions) {
const routes = [];
if (permissions.dashboard?.view) {
routes.push({ path: '/dashboard', component: Dashboard });
}
if (permissions.content?.view) {
routes.push({
path: '/content',
component: ContentLayout,
children: [
{ path: 'articles', component: Articles },
{ path: 'categories', component: Categories }
]
});
}
return routes;
}指令权限
通过自定义指令简化按钮级别的权限控制:
javascript
// Vue 自定义指令
app.directive('permission', {
mounted(el, binding) {
const requiredPerm = binding.value; // 例如 'user.create'
if (!hasPermission(requiredPerm)) {
el.parentNode?.removeChild(el);
}
}
});
// 使用
<button v-permission="'user.create'">新增用户</button>React 中可通过高阶组件或自定义 Hook 实现:
jsx
function RequirePermission({ perm, children }) {
return hasPermission(perm) ? children : null;
}
// 使用
<RequirePermission perm="user.create">
<button>新增用户</button>
</RequirePermission>组件级权限
组件级权限是指一个组件内部对不同功能的控制粒度。例如:用户详情卡片中,普通用户只能查看基本信息,管理员能看到敏感信息字段。
最佳实践
- 权限规则统一管理:将权限判断逻辑收敛到
checkPermission或ability实例中 - 后端兜底:前端权限仅做 UI 展示控制,真正的权限校验必须由后端完成
- 权限缓存:用户权限应在登录后缓存到 Store 或 localStorage
- 权限变更响应:用户权限发生变更时,应重新计算路由和菜单
- 拒绝优于允许:默认拒绝所有操作,显式允许特定权限