Firebase Firestore多租户应用账户列表权限控制规则咨询
嘿,针对你开发的Firebase Firestore多租户应用,我整理了一套贴合你需求的安全规则配置方案,帮你搞定账户授权访问和全链路安全控制!
Firestore多租户安全规则配置
核心:账户列表的授权访问控制
首先要实现的核心需求是:用户只能读取自己被授权的账户,同时限制账户的写入、更新、删除权限给管理员。结合你给出的账户文档结构,我们可以这样写规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 控制根集合accounts的访问权限 match /accounts/{accountId} { // 读取权限:仅已登录且在账户users列表中、拥有user权限的用户可访问 allow read: if request.auth != null && request.auth.uid in resource.data.users && resource.data.users[request.auth.uid].user == true; // 创建账户:确保创建者必须将自己设为管理员和主用户,避免恶意创建 allow create: if request.auth != null && request.resource.data.primaryUserID == request.auth.uid && request.resource.data.users[request.auth.uid].admin == true && request.resource.data.users[request.auth.uid].user == true; // 更新/删除账户:仅账户管理员可操作 allow update, delete: if request.auth != null && request.auth.uid in resource.data.users && resource.data.users[request.auth.uid].admin == true; } // 子集合权限控制:继承账户的授权逻辑 match /accounts/{accountId}/{subcoll=**} { // 读取子集合:仅当前账户的授权用户可访问 allow read: if request.auth != null && exists(/databases/$(database)/documents/accounts/$(accountId)) && request.auth.uid in get(/databases/$(database)/documents/accounts/$(accountId)).data.users && get(/databases/$(database)/documents/accounts/$(accountId)).data.users[request.auth.uid].user == true; // 写入子集合:可根据需求限制为管理员或授权用户,这里示例为管理员 allow write: if request.auth != null && exists(/databases/$(database)/documents/accounts/$(accountId)) && request.auth.uid in get(/databases/$(database)/documents/accounts/$(accountId)).data.users && get(/databases/$(database)/documents/accounts/$(accountId)).data.users[request.auth.uid].admin == true; } } }
规则细节解释
- 读取账户列表:通过
request.auth.uid in resource.data.users校验用户是否在账户的授权列表中,再通过user == true确认其拥有访问权限,这样用户查询accounts集合时只会返回自己有权查看的账户。 - 创建账户:强制要求创建者将自己设为
primaryUserID和管理员,避免无权限用户随意创建账户。 - 子集合访问:通过
get方法获取对应的账户文档,复用账户的授权逻辑,确保只有当前账户的授权用户才能访问其子集合数据。
额外安全增强措施
为了让规则更健壮,还可以添加以下控制:
- 校验文档结构合法性:防止写入不符合规范的账户数据,可在
accounts的create/update规则中添加:&& request.resource.data.keys().hasAll(['name', 'primaryUserID', 'users']) && request.resource.data.users is map - 限制权限篡改:确保管理员更新账户时,只能修改指定范围的用户权限(比如只能添加新用户,不能删除自身管理员权限),可在
accounts的update规则中添加:&& (request.resource.data.users.keys().difference(resource.data.users.keys()).size() <= 1 || request.resource.data.users[request.auth.uid].admin == resource.data.users[request.auth.uid].admin) - 性能优化(可选):如果用户需要访问多个账户,可以通过Cloud Function给用户设置自定义Claims,将用户有权访问的
accountId列表存入Claims,这样规则中可以直接通过request.auth.token.accountIds has accountId校验,减少Firestore的读取次数,提升性能。
测试建议
一定要用Firebase控制台的规则模拟器测试各种场景:
- 未登录用户尝试读取
accounts集合:应被拒绝 - 普通用户读取自己授权的账户:应被允许
- 普通用户读取其他账户:应被拒绝
- 管理员更新账户信息:应被允许
- 普通用户尝试更新账户:应被拒绝
- 用户访问自己账户下的子集合:应被允许
- 用户访问其他账户下的子集合:应被拒绝
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

