2. 权限三要素

很多新手刚接触 RBAC 时,总盯着「权限」这个词看。

觉得搞权限就是配一大堆开关,谁能用哪个按钮。

其实根本不是这么回事。我做过的几个大型后台项目里,如果把权限三要素拆清楚,后面八成不会出大乱子。拆不清楚?嗯,那你就等着「权限还在改」的需求天天来敲门吧。

2.1 三个要素,一个都不能少

先问个问题:你管理的到底是谁能干什么?

谁=用户,干什么=权限。那角色呢?角色就是个中间人,帮你省掉「一个人配一遍权限」这种傻事。

用一句话概括:

用户是你的系统使用者,角色是一组权限的集合,权限是对某个资源执行某个操作的许可。

举个例子你就懂了。

假设公司有个后台系统,新来了个运营专员叫大刘。大刘要能看到用户列表、能导出订单。那你会不会在他入职那天,一条条去点「查看用户」「导出订单」?如果你手工配 100 个人,你想想看,这日子还过不过了?

所以我通常的做法是:先定义好「运营专员」这个角色,里面已经把“查看用户列表、导出订单”这些权限打包好了。大刘入职,直接给他挂上这个角色,完事。

要素 定义 我项目里的习惯
用户(User) 系统的最终操作者 用户表里只存基本信息,不存权限
角色(Role) 权限的逻辑分组 角色名要有业务含义,比如“订单审核员”
权限(Permission) 对资源的操作许可 我习惯用 “资源:操作” 命名,比如 “order:export”

你可能会说,这三者听起来很简单啊。但配合起来,坑可不少。

2.2 它们之间的关系长什么样

用户和角色是多对多,角色和权限也是多对多。一个人可以既是运营又是客服,一个角色可以拥有“查看订单”和“修改订单”两种权限。

我画了一张图,把这关系捋清楚。

用户-角色-权限关系图 用 户 User 角 色 Role 角 色 Role 权 限 Permission N N N N 用户 ↔ 角色(多对多) 角色 ↔ 权限(多对多)

你看,一个用户可以有多个角色,一个角色也可以有多个用户。角色和权限也一样,一对多、多对一都容易被误解,中间表做对了,整个权限系统就稳了一半。

2.3 用户:不是一个人,而是一个身份

我曾经碰到过一个需求:某部门的领导说「小王离职了,把他的权限清掉」。结果我一查数据库,小王有 30 条直接绑定的权限记录,角色绑了 4 个,还继承了上级部门的权限。

这就是典型的「用户直接绑权限」遗留债。

我现在的原则很简单:

  • 永远不要让用户直接持有权限。用户只绑角色。
  • 用户表里别存权限字段,哪怕你觉得“就临时加一条”。临时加的东西,最后都成了永久遗留。
  • 用户的状态(启用/禁用/锁定)和角色分配是两个独立维度。禁用的用户,即使角色还在,也不能执行任何操作。
我习惯在用户表里加一个 `status` 字段,和 `role_assignments` 分离。这样即使角色没变,也能快速封停某个人。

2.4 角色:权限的“钱包”

你把角色理解成一个钱包,里面装着若干张权限卡(就是一个个具体的操作许可)。你把钱包交给谁,谁就能用里面的卡。

角色有几个关键点:

  • 角色的粒度不能太粗也不能太细。太粗(比如“超级管理员”),后果就是权限失控。太细(比如“导出3月份订单”),那跟直接绑权限没区别。
  • 角色不能嵌套角色,这会让继承关系乱成一团。我觉得层级控制在 2 层以内就够了。
  • 角色名要可读。“Role_001”这种名字,半年后你自己都看不懂。

举个例子,在一个电商后台里,我常用的角色有:

运营专员  →  查看订单、导出订单、查看商品
客服专员  →  查看订单、联系买家、创建工单
财务审计  →  查看订单、查看退款、导出财务报表

每个角色都有明确的职责边界,谁想要越界,得单独申请新的角色或修改现有角色,而不是往现有角色里塞权限。

2.5 权限:最小的操作许可单元

权限是什么?说白了,权限就是「对某个资源做某个操作」的许可。

在我的项目里,权限的命名规范通常是:

资源名 : 操作名
order:view
order:export
order:delete
user:create
user:edit

这种命名方式,一眼就能看出来「这个权限能干什么」。

这里有个常见误区:把权限写成“可以查看所有订单”或者“不可删除自己的评论”——这种带有条件判断的权限,其实更应该放在业务逻辑层,而不是权限模型层。

我曾经踩过一个坑:把“只能查看本部门的订单”写成了权限字符串。结果每个部门都要配一套权限,代码里全是魔改。后来我改成在数据层做行级过滤,权限只控制“能不能看”,具体看哪些,由数据权限规则去管。

所以,权限要关注的是“能不能”,而不是“能看到哪些”。后者是数据权限,别混在一起。

2.6 核心关系总结:一张事实表

整个 RBAC 的本质,其实就是三张关系表在互相配合:

表名 作用 字段示例
user_role 用户与角色的对应 user_id, role_id
role_permission 角色与权限的对应 role_id, permission_id
permission 权限定义表 id, resource, action, description

你想想看,只要这三张表设计得清楚,后面的接口校验、缓存策略、审计日志,都有了明确的依据。

我见过太多项目,权限三要素没分清,最后搞出一个大杂烩:用户表里有 permission 字段,角色表里有 user_id,权限表里有条件判断……那种结构,维护成本高得吓人。

所以,记住这几个原则:

  1. 用户只跟角色挂钩,不直接碰权限。
  2. 角色是一组权限的集合,不要嵌套,不要跨业务。
  3. 权限是最小许可单元,只控制「能不能」,不控制「能看到哪些」。

这三要素搞明白了,后面的所有章节,你都会觉得顺风顺水。如果还没理清楚,建议你对着那张 SVG 图多看几遍,把用户、角色、权限这三个概念像 ABC 一样刻在脑子里。