AllowedScope:同一个 action,对谁做
Permission 回答「能不能做」,Scope 回答「对谁做」。这是两个正交的维度。仅有 order:read(见 Permission 的身份)还不够——能读所有人的订单,和只能读自己的,是两种完全不同的权力。区分它们的就是 AllowedScope(数据范围),常见五档按权限由宽到窄是
Full、Group、Self、Public、None。
1 · 各 scope 下的可见行
每个 scope 对应一条过滤条件:Full 无过滤,Group 比对 row.group,Self 比对 row.owner,Public 只放行公开行,None 恒不可见。
2 · 两个轴不要混为一谈
把「能不能做」和「对谁做」拆开,授权就清晰了。同一个 action 配不同 scope,每格是一种真实的权力:
| 能力 (action) | @ Self | @ Group | @ Full |
|---|---|---|---|
article:update |
改自己的文章 | 改本组的文章 | 改所有文章 |
order:read |
看自己下的单 | 看本组负责的单 | 看全平台的单 |
order:cancel |
取消自己的单 | 取消本组的单 | 取消任意单 |
建议 ·「客服只能退本组的单」「作者只能删自己的稿」这种需求,不该靠创建新角色来解决,而是同一条 permission 配不同 scope。混淆这一点,是权限系统失控的首要原因。
3 · Scope 的取值
Full— 全部数据行,不限 owner / group。Group— 同部门/团队:row.group === me.group。Self— 仅自己创建/拥有的:row.owner === me.id。Public— 仅标记为公开的只读数据。None— 什么都看不到,等于没有这条 permission(占位/显式关闭用)。
这五档按权限排序,不是一条集合包含链。真正互相包含的只有前三档(Full ⊇ Group ⊇ Self);Public 是一道正交的过滤条件——图 1-1 里它唯一放行的那行归隔壁组的人所有,Self 与 Group 都看不到。按「Public 是
Self 的子集」去实现 WHERE 条件会漏掉公开数据。
警示 · Scope 是数据层的事。「能不能进这个页面」UI 能拦;但「这页里到底返回哪几行」必须在查询时按 scope 加 WHERE 条件——否则前端隐藏的行,直接调用 API 就能全部取到。这条约束由 Server 层 的 Repository 落实。