英文:
Combining security rules when specific field is updatable by only certain users
问题
以下是翻译的部分:
- 用户必须已登录
- 用户要么是该问题的创建者,要么是版主
- 要更新“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()));
}
}
}
英文:
I have an issue
document and I want to apply the following restrictions to update it -
- user must be logged in
- user is either the creator of that issue or user is a moderator
- to update the
status
field user must be a moderator
I can implement the first 2 rules with -
<!-- language-all: lang-js -->
allow update: if (isLoggedIn() && (isCreator() || isModerator()));
But I'm having a hard time combining proper logic for the 3rd rule with this.
On the front end, I can show/hide the status
field based on whether the current user is a moderator or not. But how can I enforce this restriction on back end with security rules?
Following is my ruleset -
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()));
}
}
}
答案1
得分: 3
我建议略微改变规则的表述:
- 文档上的管理员可以修改其中的任何字段。
- 文档的创建者可以修改所有字段,除了
status
。
这样更清晰地表明您需要在条件中更早地根据用户的角色进行分割,并可能导致如下的情况:
isModerator() || (
isCreator() && !('status' in request.resource.data.diff(resource.data).affectedKeys())
)
));
英文:
I recommend framing the rules slightly differently:
- A moderator on the document can modify any field in it.
- The creator of the document can modify all fields, except the
status
.
This makes it clearer that you need to split on the user's role earlier on in your condition, and likely leads to something like:
allow update: if (isLoggedIn() && (
isModerator() || (
isCreator() && !('status' in request.resource.data.diff(resource.data).affectedKeys())
)
));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论