第二章:RBAC基础理论——角色、权限、用户三要素
权限系统说白了就是回答三个问题:“谁”、“能干什么”、“凭什么”。RBAC(基于角色的访问控制)把它们拆成了三个核心概念:用户、角色、权限。很多初学者一上来就对着数据库表写 CRUD,结果系统上线三天就发现要改权限模型——嗯,我早期就踩过这个坑。
2.1 三要素的定义与关系
先给个最精炼的定义:
- 用户:系统的操作者,可以是人、服务账号、API 调用方。
- 角色:一组权限的集合,代表某种职能或岗位。
- 权限:对某个资源的某种操作,比如「读取订单」或「删除用户」。
它们的关系很简单:用户关联角色,角色关联权限。用户不直接持有权限,中间隔了一层角色。为什么要多这一层?你想想看,如果每个用户都直接配权限,100 个用户就得配 100 次。换成角色,10 个角色就能覆盖掉所有权限组合,改一个角色的权限,所有关联用户自动生效。
核心公式:用户 → 角色 → 权限 (多对多关系)
我在项目中遇到过一个人,觉得角色层多余,直接写了个用户↔权限的映射表。结果上线后,每次有新员工入职,运维都要手动配二十几个权限按钮……一个月后乖乖重构成 RBAC。
2.2 核心概念定义
为了后续实操不绕弯,我们把几个关键术语讲清楚。
| 术语 | 定义 | 举例 |
|---|---|---|
| 用户(User) | 权限请求的发起主体 | 用户ID: 1001,姓名:张三 |
| 角色(Role) | 权限的逻辑分组,通常与岗位对应 | “管理员”、“编辑”、“只读用户” |
| 权限(Permission) | 对某个资源操作的最小授权单位 | “创建订单”、“查看报表”、“修改密码” |
| 资源(Resource) | 被权限保护的对象 | 订单、用户、商品、报表 |
| 操作(Action) | 对资源执行的动作 | 增(create)、删(delete)、改(update)、查(read) |
这里要特别注意“权限”的定义粒度。我习惯把权限拆成“资源 + 操作”的组合,比如 order:delete 表示删除订单的权限。不要写成“管理订单”这种模糊表述——说白了,你以后没法做细粒度控制。
个人习惯:权限命名统一用「资源:操作」格式,全部小写。这样代码里好解析,前端好匹配。
2.3 三要素关系图
下面这张图把刚才讲的逻辑串起来。别跳过,它比你背三遍定义都有用。
2.4 最小权限原则
这是权限设计里最容易被忽略、也最容易翻车的一条原则。简单说:只给够用的权限,一分不多。
回忆一下我做过的第一个企业级项目:我把“超级管理员”角色一股脑给了所有运维同事,理由是“省事”。结果有个实习生误操作删了生产库的订单表……嗯,那天晚上我们全组陪他加班到凌晨三点。从那以后,我再也不敢在权限上“高估”任何人。
我曾经踩过的坑:默认角色给了“查询全部数据”的权限,导致普通用户能看到其他部门的人员工资。即使没有删除权限,光是一个“越权查看”就足够引发合规问题了。
最小权限原则落地有三个关键点:
- 角色拆分要细:不要把“报表管理”和“用户管理”塞进同一个角色。除非业务明确要求一个人同时做这两件事。
- 默认拒绝:用户没被授权就是拒绝。白名单逻辑,黑名单只会越漏越多。
- 定期审计:每三个月检查一次角色权限分配,把不再需要的权限收回来。我习惯写个定时脚本,自动标注“30天未使用”的权限。
2.5 三要素的数据库表示(设计前的常识)
虽然本章不写代码,但我还是提前给你看一下最典型的表结构,后面实操你会反复用到它。
| 表名 | 核心字段 | 备注 |
|---|---|---|
| user | id, username, status, … | 用户主表 |
| role | id, name, description, … | 角色定义表 |
| permission | id, resource, action, … | 权限定义表,resource 和 action 组合唯一 |
| user_role | user_id, role_id | 用户-角色关联表,多对多 |
| role_permission | role_id, permission_id | 角色-权限关联表,多对多 |
你想想看,如果没有中间表,用户和权限直接关联会是怎样一张爆炸表?用户 5000 人,权限 200 个,100 万条记录起步。加一个角色层,通常只需要几十个角色,关联记录数量级直接降下来。
个人经验:在设计表时,尽量给 role 表加一个 is_system 字段,用来标记内置角色(比如超级管理员)。这样避免误删。
2.6 小结:为什么 RBAC 能活这么久?
说白了,RBAC 的核心就是“间接”两个字。用户不直接跟权限打交道,而是通过角色来获取。这种设计让权限管理变得可扩展、可审计、可维护。
把三个要素的关系记牢:用户扮演角色,角色拥有权限。后面的章节(比如角色继承、权限缓存、动态权限)都建立在这个基础之上。