Firestore安全规则:实现特定字段仅管理员可更新的权限逻辑
问题描述
我有一个issue文档,希望为其更新操作设置以下权限限制:
- 用户必须已登录
- 用户是该issue的创建者,或是管理员(moderator)
- 仅管理员可更新
status字段
我已通过以下代码实现前两条规则:
allow update: if (isLoggedIn() && (isCreator() || isModerator()));
但无法将第三条规则的逻辑与之正确结合。前端可根据用户是否为管理员显示/隐藏status字段,但如何在后端通过安全规则强制该限制?
我的现有规则集如下:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { function isLoggedIn(){ return request.auth != null; } function isCreator(rsc){ return request.auth.uid == rsc.data.postedById; } function isModerator(){ return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.moderator == true; } function isStatusField(rcs){ return request.resource.data.diff(rcs.data).affectedKeys().hasAny(['status']); } match /issues/{issue} { allow read; allow create: if isLoggedIn(); allow update: if (isLoggedIn() && (isCreator() || isModerator())); } } }
解决方案
你需要修改update规则,加入对status字段修改的判断逻辑:只有当修改操作涉及status字段时,必须要求用户是管理员;如果不涉及status字段,创建者或管理员都可以操作。
调整后的update规则如下:
allow update: if isLoggedIn() && ( // 不修改status字段时,创建者或管理员均可操作 (!isStatusField(resource) && (isCreator(resource) || isModerator())) || // 修改status字段时,仅管理员可操作 (isStatusField(resource) && isModerator()) );
完整的规则集更新后如下:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { function isLoggedIn(){ return request.auth != null; } function isCreator(rsc){ return request.auth.uid == rsc.data.postedById; } function isModerator(){ return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.moderator == true; } function isStatusField(rsc){ return request.resource.data.diff(rsc.data).affectedKeys().hasAny(['status']); } match /issues/{issue} { allow read; allow create: if isLoggedIn(); allow update: if isLoggedIn() && ( (!isStatusField(resource) && (isCreator(resource) || isModerator())) || (isStatusField(resource) && isModerator()) ); } } }
逻辑说明
- 当更新操作不涉及
status字段时,保持原有的权限逻辑:已登录的创建者或管理员均可操作。 - 当更新操作包含
status字段修改时,只有管理员能通过规则校验,创建者无法修改该字段。
内容的提问来源于stack exchange,提问作者atiyar
相关产品推荐
相关产品推荐

