我正在尝试以下情况:
我的规则:
service cloud.firestore {
match /databases/{database}/documents {
//Functions
function isAuthenticated(){
return request.auth != null;
}
function isAdministrator(){
return request.auth != null && request.auth.token.name == resource.data.oid;
}
//Administrator Identity Check Point
match /admin/identity {
allow read, write: if isAdministrator();
}
//Allow Reads and Writes for All Authenticated Users
match /{document=**}{
allow read, write: if isAuthenticated();
}
}//databases/{database}/documents
}//cloud.firestore
我有什么方法可以做到这一点,实际上在测试这些规则时,测试成功是因为标签isAuthenticated()
仅调用了/{document=**}
。我也尝试过/{document!=/admin/identity}
,但不起作用。
如何编写遵循此模型的安全规则?
答案 0 :(得分:1)
也许根据您的默认用户规则,您可以检查集合是否不是管理员,例如:
//Allow Reads and Writes for All Authenticated Users
match /{collection}/{document=**}{
allow read, write: if (isAuthenticated() && collection != "admin") || isAdministrator();
}
答案 1 :(得分:0)
从6月17日开始,Firebase对Firestore安全规则进行了新的改进。
Firebase blog - 2020/06 - New Firestore Security Rules features
我们将使用
Map.get()
来获取"roleToEdit"
字段。如果文档没有该字段,则默认为"admin"
角色。然后,我们将其与用户自定义声明中的角色进行比较:
allow update, delete: if resource.data.get("roleToEdit", "admin") == request.auth.token.role;
假设您通常在授予访问权限之前先检查用户是否满足相同的三个条件:他们是产品的所有者还是管理员用户。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function privilegedAccess(uid, product) {
let adminDatabasePath = /databases/$(database)/documents/admins/$(uid);
let userDatabasePath = /databases/$(database)/documents/users/$(uid);
let ownerDatabasePath = /databases/$(database)/documents/$(product)/owner/$(uid);
let isOwnerOrAdmin = exists(adminDatabasePath) || exists(ownerDatabasePath);
let meetsChallenge = get(userDatabasePath).data.get("passChallenge", false) == true;
let meetsKarmaThreshold = get(userDatabasePath).get("karma", 1) > 5;
return isOwnerOrAdmin && meetsChallenge && meetsKarmaThreshold;
}
match /products/{product} {
allow read: if true;
allow write: if privilegedAccess();
}
match /categories/{category} {
allow read: if true;
allow write: if privilegedAccess();
}
match /brands/{brand} {
allow read, write: if privilegedAccess();
}
}
}
相同条件允许访问三个不同集合中的文档。
这是我们第一次引入
if/else
控制流,我们希望它可以使规则更加平滑和强大。
这是一个使用三元运算符为写操作指定复杂条件的示例。
用户可以在两种情况下更新文档:首先,如果他们是管理员用户,则需要设置字段overrideReason
或approvedBy
。其次,如果他们不是管理员用户,则更新必须包括所有必填字段:
allow update: if isAdminUser(request.auth.uid) ?
request.resource.data.keys().toSet().hasAny(["overrideReason", "approvedBy"]) :
request.resource.data.keys().toSet().hasAll(["all", "the", "required", "fields"])
可以在三元数之前表达它,但这是一个更为简洁的表达。 ;)