RBAC(Role-Based Access Control,基于角色的访问控制)是一种广泛应用于权限管理的模型,特别是在后台系统或企业级应用中。它的核心思想是通过“角色”来桥接用户和权限,从而实现灵活、高效的权限分配和管理。以下是对 RBAC 的详细解释,以及结合 MySQL 如何实现它的具体方案。
RBAC 的基本概念
- 用户 (Users):系统的操作主体,例如管理员、编辑员等。
- 角色 (Roles):权限的集合,一个角色可以包含多个权限,用户通过绑定角色间接获得权限。
- 权限 (Permissions):具体的操作能力,例如“查看用户”“删除文章”等。
- 关系:
- 用户和角色:多对多(一个用户可以有多个角色,一个角色可以分配给多个用户)。
- 角色和权限:多对多(一个角色可以有多个权限,一个权限可以分配给多个角色)。
RBAC 的优势
- 简化管理:通过角色批量分配权限,不需要为每个用户单独设置。
- 灵活性:角色可以动态调整,权限变更时只需修改角色而非每个用户。
- 可扩展性:支持权限层级(如菜单和按钮)或复杂的业务需求。
RBAC 在 MySQL 中的表设计
以下是我之前提到的表结构,专门为 RBAC 设计:
-
用户表 (users):
CREATE TABLE users ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, status TINYINT DEFAULT 1 COMMENT '1=正常,0=禁用' ); -
角色表 (roles):
CREATE TABLE roles ( id BIGINT PRIMARY KEY AUTO_INCREMENT, role_name VARCHAR(50) NOT NULL UNIQUE, description VARCHAR(255), status TINYINT DEFAULT 1 COMMENT '1=启用,0=禁用' ); -
权限表 (permissions):
CREATE TABLE permissions ( id BIGINT PRIMARY KEY AUTO_INCREMENT, permission_name VARCHAR(100) NOT NULL UNIQUE, permission_code VARCHAR(100) NOT NULL UNIQUE, type TINYINT NOT NULL COMMENT '1=菜单,2=操作', parent_id BIGINT DEFAULT 0 COMMENT '父权限ID' ); -
用户-角色关系表 (user_roles):
CREATE TABLE user_roles ( user_id BIGINT NOT NULL, role_id BIGINT NOT NULL, PRIMARY KEY (user_id, role_id), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE ); -
角色-权限关系表 (role_permissions):
CREATE TABLE role_permissions ( role_id BIGINT NOT NULL, permission_id BIGINT NOT NULL, PRIMARY KEY (role_id, permission_id), FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE, FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE );
RBAC 的操作示例
1. 添加角色
给系统添加一个“管理员”角色:
INSERT INTO roles (role_name, description, status)
VALUES ('管理员', '系统最高权限', 1);
2. 添加权限
添加“用户查看”和“用户删除”两个权限:
INSERT INTO permissions (permission_name, permission_code, type, parent_id)
VALUES
('用户管理', 'user:manage', 1, 0),
('用户查看', 'user:view', 2, 1),
('用户删除', 'user:delete', 2, 1);
3. 为角色分配权限
将“用户查看”和“用户删除”权限分配给“管理员”角色(假设角色 id = 1):
INSERT INTO role_permissions (role_id, permission_id)
VALUES
(1, 2), -- 用户查看
(1, 3); -- 用户删除
4. 为用户分配角色
将用户 id = 1(如 admin)绑定到“管理员”角色:
INSERT INTO user_roles (user_id, role_id)
VALUES (1, 1);
5. 查询用户的权限
查询用户 admin(id = 1)的所有权限:
SELECT DISTINCT p.permission_name, p.permission_code
FROM users u
JOIN user_roles ur ON u.id = ur.user_id
JOIN role_permissions rp ON ur.role_id = rp.role_id
JOIN permissions p ON rp.permission_id = p.id
WHERE u.id = 1;
结果:
| permission_name | permission_code |
|---|---|
| 用户查看 | user:view |
| 用户删除 | user:delete |
RBAC 的扩展
- RBAC0:基础模型,只有用户-角色-权限的关系,如上述设计。
- RBAC1:支持角色继承。例如,“超级管理员”继承“管理员”的权限。
- 在
roles表中加一个parent_role_id字段。
- 在
- RBAC2:添加约束,如互斥角色(不能同时拥有角色A和B)。
- 需要额外的规则表来定义约束。
- RBAC3:结合 RBAC1 和 RBAC2,功能最强大。
角色继承示例
修改 roles 表:
ALTER TABLE roles ADD COLUMN parent_role_id BIGINT DEFAULT 0;
查询继承权限:
WITH RECURSIVE role_hierarchy AS (
SELECT id, parent_role_id
FROM roles
WHERE id = 1
UNION ALL
SELECT r.id, r.parent_role_id
FROM roles r
JOIN role_hierarchy rh ON r.id = rh.parent_role_id
)
SELECT DISTINCT p.permission_name, p.permission_code
FROM role_hierarchy rh
JOIN role_permissions rp ON rh.id = rp.role_id
JOIN permissions p ON rp.permission_id = p.id;
实际应用中的优化
- 索引:为
user_roles和role_permissions的外键字段加索引,提升查询性能。 - 缓存:将权限数据缓存到 Redis 中,减少数据库查询。
- 动态权限:支持运行时修改权限(如通过管理界面),确保实时更新。
RBAC 是权限管理的经典模型,简单却强大。
前端工程师、程序员

浙公网安备 33010602011771号