如何高效实现Serverless API的用户权限获取与校验?
针对你每次请求都读取Firestore权限导致大量读取操作的问题,这里有几个实用的优化方案:
1. 将权限信息嵌入JWT Payload
登录生成JWT时,直接把用户的权限列表/角色信息写入Token的Payload中(比如permissions: ["read:data", "write:user"]或者role: "admin")。这样每次API验证Token时,只需解析Payload就能获取权限,完全跳过Firestore读取步骤。
- 注意事项:
- 权限更新时,旧Token仍会生效,建议:
- 设置较短的Token过期时间(比如15-30分钟),配合刷新Token机制,权限更新后用户下次刷新Token就能拿到新权限
- 在Payload中加入权限版本号(
permission_version: 1),API端维护一个最新版本号的缓存,若Token中的版本号过期,再去Firestore拉取最新权限并更新缓存
- 不要在Payload中存放敏感信息,因为JWT是Base64编码而非加密,可被解码
- 权限更新时,旧Token仍会生效,建议:
2. 缓存用户权限
在API层添加缓存层(比如Redis、内存缓存,或者Serverless平台自带的缓存服务),以用户ID为Key存储权限信息,设置合理的过期时间(比如5-15分钟):
用户首次请求时,从Firestore读取权限并存入缓存
后续请求直接从缓存读取权限进行校验
当用户权限更新时,主动清除对应缓存Key,确保下次请求能拉取最新权限
适合场景:权限不频繁变更的业务,能大幅减少Firestore读取量,同时兼顾权限更新的时效性
3. 使用Firebase自定义Claims(若基于Firebase Auth)
如果你的登录系统用的是Firebase Auth,可以利用Firebase的自定义Claims功能:
后台通过Firebase Admin SDK给用户设置自定义Claims(比如
setCustomUserClaims(uid, { role: "admin", permissions: ["manage:users"] }))用户登录后获取的ID Token会自动包含这些Claims,API验证Token时直接解析Claims即可拿到权限
权限更新后,用户需要重新登录或调用
getIdToken(true)强制刷新Token才能获取新的Claims优势:无需自己维护JWT的生成和权限嵌入逻辑,Firebase会自动处理Token的签名和验证,安全性更高
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| JWT嵌入权限 | 完全避免DB读取,性能最优 | 权限更新有延迟,需配合短过期/版本号 |
| 缓存权限 | 平衡性能与时效性,实现简单 | 需要维护缓存,权限更新需主动失效缓存 |
| Firebase自定义Claims | 集成度高,安全可靠,无需自己造轮子 | 依赖Firebase Auth,权限更新需用户刷新Token |
你可以根据自己的业务场景选择最合适的方案,比如权限极少变更的系统优先选JWT嵌入,用Firebase的话直接用自定义Claims最省心。
内容的提问来源于stack exchange,提问作者CSSer

