KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
权限与多租户课 · 课程导读 — keel 龙骨
权限与多租户:从若依模型到注解式鉴权 的参考信息:权限与多租户课 · 课程导读
权限是后端系统里最容易写错、又最难被测出来的一层:错了不会报错,只会让某个人看到别人的数据。这门课从国内最常见的若依式模型(菜单 + 按钮 + 接口 + 数据范围)出发,一路讲到多租户的身份体系、RBAC 与 ACL 的分工、以及注解式声明鉴权的正确落地方式。全程使用一套可运行的配套项目,每个结论都有真实输出和可跑的越权用例。
你现在的起点
- 会写登录接口、知道 token 怎么发出去,但权限判定基本靠
if硬写; - 知道 RBAC 这个词,说得出"用户-角色-权限"三张表,但没独立设计过一套;
- 接过"多租户"的需求,只在每张表加了个
tenant_id字段; - 遇到过"接口返回 403 但说不清是哪一层拦的"。
如果你符合这三条,这门课就是为你写的。
一条能走通的学习路径
00 全景地图:认证 / 授权 / 数据隔离,三件事各管什么
→ 01 若依式权限从零手搓:五张表 + 三层权限(菜单/接口/数据)
→ 02 数据权限:四种 scope 与「把权限塞进 SQL」的两种做法
→ 03 落地形态:函数内判定 → 依赖注入 → 注解,谁才是答案
→ 04 多租户身份体系:user / member / tenant 三级 id 的分工
→ 05 隔离与泄密面:越权、404 与 403、上下文串味
→ 06 RBAC 的边界与 ACL:为什么"能改"不能是布尔值
→ 07 缓存与一致:权限改了多久生效
你会反复用到的一个主案例
配套项目里这套演示数据,全课都在它身上做实验:
| 租户 | 人 | 身份 | 角色 | 数据范围 |
|---|---|---|---|---|
| Acme 科技 | Alice | m_alice_acme |
租户管理员 | 全部数据 |
| Acme 科技 | Bob | m_bob_acme |
研发 | 仅本人 |
| Acme 科技 | Carol | m_carol_acme |
运营 | 仅本部门 |
| Globex | Alice | m_alice_globex |
访客 | 仅本人 |
注意 Alice 出现了两次:同一个人,在两个租户里是两个完全不同的身份,
角色和数据范围都不一样。这是 04 章要展开的核心事实,也是"多租户"区别于"多用户"的根本。
三个必须先纠偏的认知
- 菜单可见 ≠ 接口可调。 若依式 RBAC 里菜单和接口是两套授权。只做菜单的系统,把请求换成 curl 就能越权——这是最常见、也最致命的一类漏洞。
- 多租户不等于每张表加一个
tenant_id。 加了字段但查询时忘了带条件,等于没隔离。真正的隔离是"默认带条件、且无法被绕过"的机制。 - RBAC 不是终点。 角色能回答"这个岗位能做什么",回答不了"这个人对这一条数据能做什么"。后者要么靠数据范围(行级),要么靠 ACL(资源级),要么两者都要。
配套项目与本课的关系
project/ 是一套可运行的实现(SQLite + FastAPI,14 条 pytest + 10 个真实 HTTP 用例)。课程里每一段"实测输出"都是从它跑出来的,代码块旁的文件行号都能在 project/ 里找到对应实现。
学习顺序建议:先读正文建立判断力,再照着 project/demo.py 跑一遍,最后自己改数据制造越权。
学完这门课你能做什么
- 从零设计一套权限数据模型(表结构 + 权限点命名 + 角色与数据范围),并说清每张表为什么存在;
- 判断一段鉴权代码属于哪种落地形态,知道哪种会漏、哪种不会;
- 设计多租户身份体系,说清
user_id与租户内身份 id 为什么必须分开; - 解释 403 与 404 的取舍,以及哪些信息绝对不能通过状态码泄露;
- 解释 RBAC 的适用边界、何时必须上 ACL,并给出访问级别带权重的实现;
- 定位"权限改了没生效"这类缓存一致性问题。
前置要求
- 会用 SQL(SELECT/JOIN/索引基础),写过至少一个带鉴权的接口;
- 了解 HTTP 状态码 401/403/404 的区别;
- 建议先读 Redis 部署形态课 的第 07 章——权限判定结果要放进缓存时,那里的监控与失效策略直接适用。