多租户 SaaS 控制台的最小可用鉴权分层
这是一篇示例方案笔记,用于演示 /tech/ 栏目写作格式,正式发布前可整篇替换。
多租户系统的权限模型坏掉,多半不是加密算法选错了,而是三类完全不同的凭证被混用成了同一套。
三类凭证,三种生命周期
| 凭证 | 使用者 | 生命周期 | 泄露爆炸半径 |
|---|---|---|---|
| 会话 Cookie | 浏览器里的真人 | 小时~天 | 单个用户 |
| API Token | 客户的服务端程序 | 月~年 | 单个租户 |
| 服务间凭证 | 自己的后端互调 | 进程存续期 | 全系统 |
混用的典型症状:给定时任务发一个"永久有效的用户 Token"——它既没有会话的过期保护,又携带用户级权限,泄露后连租户隔离都拦不住它。
分层落地要点
- 会话层只做交互:HttpOnly + SameSite,过期时间给到小时级,配合滑动续期;
- API Token 建在租户而非用户之下:权限是"这个程序能读写哪类资源"的静态声明,创建时选定、按需轮换、明文只在创建时展示一次;
- 服务间凭证绝不向下透传:内部调用需要用户身份时,用短时效的内部断言(几十秒)表达,而不是转发用户 Token。
校验路径统一收口
所有中间件汇到同一个决策函数:凭证类型 → 解析 → 租户归属校验 → 权限点检查。任何一个环节失败都返回同构错误,不泄露"资源存在但无权限"与"资源不存在"的差别。权限点用 资源:动作 字符串枚举,别用位运算——一年后没人记得 bit 3 是什么。
小结
先分凭证类型,再谈加密细节。爆炸半径决定了每一类凭证该多"短命",这一层想清楚了,后面加 RBAC、加审计都是顺水推舟。