前端权限控制设计:避免硬编码权限判断
引言
前端权限控制是应用安全的重要组成部分。如果每个页面都写死权限判断,就像在每个房间装一把不同的锁,管理起来非常困难。
权限控制设计的必要性
近期看到一些项目,权限判断散落在大量文件中,修改一个权限规则需要修改多处,导致维护成本极高。这种分散的管理方式容易导致权限混乱。
反面案例
// 反面案例:分散的权限判断
// Page1.jsx
if (user.role !== 'admin') {
return <div>无权限</div>;
}
// Page2.jsx
if (!user.permissions.includes('user:view')) {
return <div>无权限</div>;
}
// Page3.jsx
if (user.role !== 'admin' && user.role !== 'manager') {
return <div>无权限</div>;
}
// ... 还有更多页面
上述代码中,权限判断散落各处,维护成本高昂。
前端权限控制方案
1. 基于角色的权限控制(RBAC)
// 权限配置
const permissions = {
admin: ['*'],
manager: ['user:view', 'user:edit', 'report:view'],
user: ['user:view', 'profile:edit']
};
// 权限检查函数
export function hasPermission(user, permission) {
const userPermissions = permissions[user.role] || [];
return userPermissions.includes('*') || userPermissions.includes(permission);
}
Vue 指令示例:
<!-- 使用 v-permission -->
<template>
<button v-permission="'user:edit'">编辑用户</button>
<button v-permission="'user:delete'">删除用户</button>
</template>
2. 路由权限控制
// router/index.js
const routes = [
{
path: '/admin',
component: AdminLayout,
meta: { requiresAuth: true, roles: ['admin'] },
children: [
{
path: 'users',
component: UserManagement,
meta: { permission: 'user:manage' }
}
]
}
];
// 路由守卫
router.beforeEach((to, from, next) => {
const user = store.getters.user;
if (to.meta.requiresAuth && !user) {
next('/login');
return;
}
if (to.meta.roles && !to.meta.roles.includes(user.role)) {
next('/403');
return;
}
if (to.meta.permission && !hasPermission(user, to.meta.permission)) {
next('/403');
return;
}
next();
});
3. 组件级权限控制
// components/Permission.jsx
function Permission({ permission, children, fallback = null }) {
const user = useUser();
if (!hasPermission(user, permission)) {
return fallback;
}
return children;
}
// 使用示例
function UserPage() {
return (
<div>
<h1>用户管理</h1>
<Permission permission="user:create">
<button>新建用户</button>
</Permission>
<Permission permission="user:export" fallback={<span>无导出权限</span>}>
<button>导出数据</button>
</Permission>
</div>
);
}
最佳实践与原则
1. 权限设计原则
- 集中管理:权限配置集中存放
- 最小权限:只给必要的权限
- 动态获取:从服务端获取权限
- 前端校验:用户体验,后端兜底
2. 代码规范
// 权限常量定义
const PERMISSIONS = {
USER_VIEW: 'user:view',
USER_CREATE: 'user:create',
USER_EDIT: 'user:edit',
USER_DELETE: 'user:delete'
};
// 权限组合
const ADMIN_PERMISSIONS = [
PERMISSIONS.USER_VIEW,
PERMISSIONS.USER_CREATE,
PERMISSIONS.USER_EDIT,
PERMISSIONS.USER_DELETE
];
// 权限检查
const canEditUser = hasPermission(user, PERMISSIONS.USER_EDIT);
总结
权限控制是应用安全的基石。建议采用集中管理的权限系统,而非分散的硬编码判断。良好的权限设计能让应用更安全、更易维护。


