用户、角色、权限三要素,权限粒度设计
三要素到底是什么关系?
权限模型最核心的就仨东西:用户、角色、权限。很多刚入行的同学容易搞混,以为这不过就是建几张表的事。
我在项目中见过不少团队,一开始直接给用户挂权限,搞到最后权限表几万行,每次上线改权限都提心吊胆。说白了,角色就是用户和权限之间的桥梁。没有角色,你的权限系统就是一盘散沙。
| 要素 | 定义 | 我见过的反面教材 |
|---|---|---|
| 用户 | 系统操作的实体,可以是人、API调用方、服务账号 | 直接把数据库账号当用户用,权限全是硬编码 |
| 角色 | 权限的逻辑分组,代表一类业务身份 | 一个用户一个角色,角色数比用户还多 |
| 权限 | 对资源的操作许可,增删改查都是权限 | 权限粒度只有菜单级别,按钮状态全靠前端控制 |
你想想看,没有角色会怎样?比如要给100个新员工加「工单查看」权限,你难道要挨个去绑定?有角色的话,把这100人扔进「工单客服」角色组就完事了。
权限粒度:你到底能控制到什么程度?
权限粒度这个问题,每次我跟团队设计新系统时都要争论半天。太粗了不安全,太细了维护成本爆炸。
我从项目经验中总结出了三个层级:
- 粗粒度:菜单权限——能看到哪些页面。这算最基础的。我记得有家公司,后端验证只写了个if(user.hasRole("admin")),结果测试小姐姐随便改个返回值就进了后台……
- 中粒度:操作权限——菜单里的按钮能不能点。比如「删除订单」这个按钮,普通客服不应该看到。
- 细粒度:数据权限——同一张单据,你能看自己的,我能看全部的。这才是真正麻烦的地方。
我的经验: 不要一上来就搞细粒度。先跑通菜单和操作两级,等业务明确了再加数据权限。否则你会被无穷无尽的「部门范围」「区域范围」「组织层级」给绕晕。
举个例子。我曾经接手过一个遗留系统,里面权限字段有20多种,什么「仅本人」「本部门」「本部门及下级」「公司级」「自定义范围」……最后我一看,真实的场景其实只需要三种:个人、团队、全部。改完之后,权限配置量直接降了60%——你想想,多出来的那些「假粒度」全都在浪费开发时间。
实战中怎么设计这三要素的表结构?
直接上我最常用的建模方式。这不是什么花活,就是五张核心表:
用户表 (user)
├── id
├── name
└── status
角色表 (role)
├── id
├── role_name -- 比如“订单管理员”
└── role_type -- 区分业务角色 vs. 系统角色
用户角色关联表 (user_role)
├── user_id
└── role_id
权限表 (permission)
├── id
├── resource -- 资源标识,如 "order:edit"
├── action -- read / write / delete
└── description
角色权限关联表 (role_permission)
├── role_id
└── permission_id
这张表结构我在三个项目中用过,每次新项目启动我都直接拿这套基础骨架出来改,效率高很多。
小提醒: 用户角色关联、角色权限关联一定要用硬删除+日志方式,别搞真删。万一哪天权限配错了,你还能从日志里溯源是谁在什么时候改的——这在安全审计里是刚需。
权限粒度设计,要避开哪些坑?
嗯,这里要注意几个常见的问题,我一个个说清楚。
- 角色爆炸: 别给「客服主管」「客服经理」「客服总监」各建一个角色。更好的做法是抽象成「工单处理员」和「工单审批员」,再用部门维度限制范围。我曾经见过一个系统里300个角色,每次上线改权限比改代码还痛苦。拆成10个角色后,管理轻松多了。
- 权责分离: 财务里「制单」和「审批」不能是同一个人。这个在角色设计时就得考虑好,别留后门。我见过一个系统因为没做这层隔离,让一个人既做账又审核,出了好几万的对账差错。
- 权限优先级: 同一个用户有「拒绝」和「允许」两个角色怎么办?业界惯例是拒绝优先。别搞成谁后绑定谁生效,那是给自己埋雷。
警告: 数据库别直接设权限继承的层级结构,比如「角色A继承角色B」。这会让权限计算陷入递归死循环。我踩过这个坑——某个用户被递归赋值了7层角色,权限加载耗时从50ms飙升到3秒。后来老老实实拍平存储,世界清净了。
我常用的权限粒度矩阵
每次评审时我都会拿出这个表格,跟产品经理对齐预期。
| 粒度级别 | 典型示例 | 实现难度 | 维护成本 |
|---|---|---|---|
| 菜单级 | 能看到订单管理页 | 低 | 低 |
| 操作级 | 能点击「导出」按钮 | 中 | 中 |
| 数据级 | 只能看本部门的订单 | 高 | 高 |
| 字段级 | 只能查看客户姓名,不能看到手机号 | 极高 | 极高 |
我个人习惯:如果业务没有明确要求字段级权限,就先不做。真的需要时,可以用数据脱敏来处理,成本低不少。
好了,到目前为止,我们把用户、角色、权限这三个东西的关系理清楚了,也知道了粒度怎么划才不会让自己后期痛苦。画一张简单的图帮大家把逻辑串起来。
这张图说清楚了:用户挂角色,角色挂权限,权限再按粒度切分级。千万别跳过角色层直接挂权限,那是给自己后期留坑。我在推进权限重构时,最常跟团队讲的就是——角色承载的是「业务身份」,权限承载的是「操作权利」,这两者必须解耦。