**用户(User)** + **角色(Role)** + **权限(Permission)** = **三元组关系模型**
具体来说:
- **用户**:访问系统的主体。可以是一个人、一个服务账号、一个API消费者。用户的属性天生不稳定——入职、转岗、离职,这些变化每天都在发生。
- **角色**:权限的分组容器。它代表组织内的一类职责,比如“数据库管理员”、“订单审核员”。角色是稳定的,一个公司的职责划分通常几年才变一次。
- **权限**:对系统资源的操作能力。比如“创建订单”、“读取用户信息”、“删除服务器”。权限通常直接对应到系统的某个功能或接口。
它们之间的关系只有两个:
1. **用户关联角色**(多对多关系)
2. **角色拥有权限**(多对多关系)
**用户与权限之间没有直接关联。这是整个RBAC模型的红线。**
### 为什么需要角色这个中间层?
我当年刚接触RBAC时也有这个疑问。直接给用户分配权限不是更直接吗?为什么要多搞一个“角色”出来?
后来在为一个电商平台做权限改造时,我彻底想明白了。
**直接授权的问题**:
假设公司有50个运营人员,每个人都需要“查看订单”和“导出报表”的权限。如果直接授给用户:
- 这50个人每人要配2个权限 = 100次操作
- 如果这50个人配置完全一样,就会产生50份重复数据
- 当“导出报表”这个权限需要升级或废弃时,要通知50个人
现在用角色来管理:
- 创建“运营专员”角色,赋予“查看订单”+“导出报表”权限
- 把50个运营人员都挂到这个角色上
- 权限变更时,只需要改角色,50个人自动生效
这就是RBAC的精髓——**对权限的变更进行集中化管理**。
**我曾经踩过的一个坑**:
有个遗留系统,表结构里直接设计了`user_permission`表,存了用户和权限的直接关联。后来业务扩张,用户数从100涨到10000,这张表膨胀到近百万条记录,权限变更时DBA叫苦连天。
我当时意识到:**任何绕开角色层的设计,在规模扩大后都会出问题**。只要是直接授给用户权限的地方,将来一定是灾难。
### 角色可以叠加吗?
可以,而且很多场景都需要角色叠加。
比如一个用户既是“开发工程师”,又是“项目管理员”。前者只能看代码、提MR,后者可以创建分支、管理版本发布。这个人同时拥有两个角色的全部权限。
这就是角色的核心价值:**组合和复用**。
### 一张表看懂模型对比
| 特性 | 直接授权 | 基于角色的授权 |
|------|---------|---------------|
| 维护成本 | 用户数 × 权限数 | 角色数 + 用户与角色的关联 |
| 权限变更影响 | 每个用户单独改 | 只改角色,用户自动更新 |
| 扩展性 | 差,1000用户时已无法维护 | 好,支持万级用户 |
| 权限审计 | 需要扫全表关联 | 只需要查角色定义 |
| 典型场景 | 小工具、原型系统 | 企业级系统、微服务架构 |
### 我习惯怎么定义这几个概念?
在实际项目中,我一般这样定义:
- **用户**:用人话来说,就是“谁”在操作。用唯一标识符表示,比如员工ID、邮箱、AK/SK。
- **角色**:描述“这类人”是干什么的。比如“运维主管”代表可以登录服务器、查看日志、重启服务;“财务审核”代表只能查看待审核的报销单。
- **权限**:描述“能干什么”。在接口层面,权限通常表示为`HTTP方法 + 资源路径`,比如`POST /api/orders`、`GET /api/reports`。
### 从理论到实践的第一步
在你开始写代码之前,先做这件事:**把你的业务系统中的所有功能点列出来,分门别类,抽象成角色**。
这步工作决定了你的权限体系是否灵活、是否可持续。RBAC不是数据库设计,而是组织管理的映射。
好了,关于用户-角色-权限的三元组关系,今天就聊到这里。记住这个核心模型,后面的所有内容——包括角色继承、约束条件、权限缓存、接口映射——都是在这个基础上延伸出来的。