之前后台管理系统的权限和角色权限都是返回具体值(比如‘admin|user’或者‘10001 | 10002’),前端本地维护一份类似的文件,每次去遍历来获取用户的具体权限列表。随着系统的迭代,需求的变化,权限维护起来就更加复杂了。今天分享一下,如何使用按位运算符来实现易于维护迭代权限系统。
以下是我之前一个项目的后台管理系统的具体实操,给大家借鉴一下
权限拆分
- 操作权限
- 用户权限
- 角色
- 角色权限
权限配置
//permissions.ts
export const READ = 1<<1; // 1 读取
export const WRITE = 1<<2;// 2 编辑
export const DELETE = 1<<3;// 4 删除
export const ADD = 1<<4;// 8 添加
export const SHARE = 1<<5;// 16 分享
export const UPLOAD_FILES = 1<<6;// 32 上传文件
export const MANAGE_USERS = 1<<7;// 64 管理用户
export const MANAGE_ROLES = 1<<8;// 128 管理角色
export const MANAGE_MENUS = 1<<9;// 256 管理菜单
// 用户权限
export const USER_PERMISSIONS = {
READ,
WRITE,
DELETE,
ADD,
SHARE,
UPLOAD_FILES,
MANAGE_USERS,
MANAGE_ROLES,
MANAGE_MENUS,
}
// 角色
export const ROLE = {
admin: 1<<0, // 1 管理者
generaler: 1<<1, // 2 普通员工
financer: 1<<2, // 4 财务员
operationaler: 1<<3, // 8 运营员,
}
type RolePermissions = {
[key: string]: number
}
// 角色权限
export const ROLE_PERMISSIONS:RolePermissions = {}
// 角色权限 添加管理员权限
ROLE_PERMISSIONS.admin =
USER_PERMISSIONS.ADD
| USER_PERMISSIONS.WRITE
| USER_PERMISSIONS.DELETE
| USER_PERMISSIONS.ADD
| USER_PERMISSIONS.SHARE
| USER_PERMISSIONS.UPLOAD_FILES
| USER_PERMISSIONS.MANAGE_USERS
| USER_PERMISSIONS.MANAGE_ROLES
| USER_PERMISSIONS.MANAGE_MENUS;
// 角色权限 添加普通员工权限
ROLE_PERMISSIONS.generaler =
USER_PERMISSIONS.READ
| USER_PERMISSIONS.WRITE
// 角色权限 添加财务员权限
ROLE_PERMISSIONS.financer =
USER_PERMISSIONS.READ
| USER_PERMISSIONS.WRITE
| USER_PERMISSIONS.UPLOAD_FILES
// 角色权限 添加运营员权限
ROLE_PERMISSIONS.operationaler =
USER_PERMISSIONS.READ
| USER_PERMISSIONS.ADD
| USER_PERMISSIONS.WRITE
| USER_PERMISSIONS.DELETE
| USER_PERMISSIONS.UPLOAD_FILES
// 菜单权限
export const MENU_PERMISSIONS = {
dashbord: 1<<0,// 1 仪表盘菜单
users: 1<<1,// 2 用户管理菜单
roles: 1<<2,// 4 角色管理菜单
files: 1<<3,// 8 文件管理菜单
settings: 1<<4,// 16 设置菜单
orders: 1<<5,// 32 订单管理菜单
products: 1<<6,// 64 商品管理菜单
customers: 1<<7,// 128 客户管理菜单
suppliers: 1<<8,// 256 供应商管理菜单
}
export default {
ROLE,
USER_PERMISSIONS,
MENU_PERMISSIONS,
ROLE_PERMISSIONS,
}
权限操作
- 初始化用户权限
// 1. 定义用户权限,使用按位或操作符 | 添加权限
let user1_permisson = READ|WRITE|SHARE|DELETE|ADD;
console.log('user1_permisson',user1_permisson);
// 2. 判断用户是否有某个权限
console.log('================ user1_permisson has permission =============');
console.log('user1_permisson has READ',hasPermission(user1_permisson,READ));
console.log('user1_permisson has DELETE',hasPermission(user1_permisson,DELETE));
console.log('user1_permisson has MANAGE_ROLES',hasPermission(user1_permisson,MANAGE_ROLES));
// 3. 获取用户的权限列表
console.log('================ user1_permisson permissions list =============');
console.log('user1_permisson permissions list',getPermissionsList(user1_permisson,USER_PERMISSIONS))
- 添加用户权限
console.log('================ user1_permisson add permission =============');
//使用按位或操作符 | 添加权限
user1_permisson |= MANAGE_ROLES;
user1_permisson |= MANAGE_USERS;
console.log('user1_permisson has MANAGE_ROLES',hasPermission(user1_permisson,MANAGE_ROLES));
console.log('user1_permisson has MANAGE_ROLES',hasPermission(user1_permisson,MANAGE_USERS));
console.log('user1_permisson permissions list',getPermissionsList(user1_permisson,USER_PERMISSIONS))
- 删除用户权限
console.log('================ user1_permisson delete permission =============');
//使用按位与& 和按位取反~来删除某个权限
user1_permisson &= ~SHARE;
user1_permisson &= ~ADD;
console.log('user1_permisson has SHARE',hasPermission(user1_permisson,SHARE));
console.log('user1_permisson has ADD',hasPermission(user1_permisson,ADD));
console.log('user1_permisson permissions list',getPermissionsList(user1_permisson,USER_PERMISSIONS))
PS 上述代码用到两个工具函数,权限判断和获取权限列表名
- 权限判断
/**
* 检查用户是否拥有指定的权限。
*
* @param permissions - 用户拥有的所有权限的位掩码。
* @param permission - 需要检查的特定权限的位掩码。
* @returns 如果用户拥有指定的权限,则返回 true;否则返回 false。
*/
function hasPermission(permissions: number, permission: number) {
// 使用按位与运算符 (&) 检查用户权限中是否包含指定权限
return (permissions & permission) === permission;
}
- 获取权限列表名
/**
* 根据用户的权限位掩码和所有权限的对象,获取用户拥有的权限列表。
*
* @param permission - 用户拥有的所有权限的位掩码。
* @param permissions - 包含所有权限名称和对应位掩码的对象。
* @returns 一个数组,包含用户拥有的所有权限的名称。
*/
function getPermissionsList(permission: number, permissions: any) {
const permissionsList = [];
for (const [permissionName, permissionValue] of Object.entries(permissions)) {
if ((permission & permissionValue as number) === permissionValue) {
permissionsList.push(permissionName);
}
}
return permissionsList;
}
使用按位运算符可以很方便的一套维护性很强的权限系统,大家可以试一下