Firebase 特定文档的Firestore安全规则

Firebase 特定文档的Firestore安全规则,firebase,firebase-authentication,google-cloud-firestore,firebase-security,Firebase,Firebase Authentication,Google Cloud Firestore,Firebase Security,我尝试应用以下情况: 除管理员文档外,所有经过身份验证的用户都具有对数据库的读写访问权限 管理员文档只能供他读写 我的规则: service cloud.firestore { match /databases/{database}/documents { //Functions function isAuthenticated(){ return request.auth != null; } function isAdministrator

我尝试应用以下情况:

  • 除管理员文档外,所有经过身份验证的用户都具有对数据库的读写访问权限
  • 管理员文档只能供他读写
我的规则:

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}
,但它不起作用


如何编写遵循此模型的安全规则?

也许您可以在默认用户规则上检查集合是否为admin,如下所示:

//Allow Reads and Writes for All Authenticated Users
match /{collection}/{document=**}{
  allow read, write: if (isAuthenticated() && collection != "admin") || isAdministrator();
}

自6月17日以来,Firebase对Firestore安全规则进行了新的改进

新的映射方法 我们将使用
Map.get()
获取
“roleToEdit”
字段。如果文档没有该字段,它将默认为
“admin”
角色。然后,我们将其与用户自定义声明中的角色进行比较:

允许更新、删除:if resource.data.get(“roleToEdit”、“admin”)==request.auth.token.role;
局部变量 假设您通常在授予访问权限之前检查用户是否满足相同的三个条件:他们是产品的所有者或管理员用户

rules_version='2';
服务云.firestore{
匹配/databases/{database}/documents{
功能权限访问(uid、产品){
让adminDatabasePath=/databases/$(数据库)/文档/admins/$(uid);
让userDatabasePath=/databases/$(数据库)/文档/users/$(uid);
让ownerDatabasePath=/databases/$(database)/documents/$(product)/owner/$(uid);
让IsOwnerRorAdmin=exists(adminDatabasePath)| | exists(ownerDatabasePath);
让MeetChallenge=get(userDatabasePath).data.get(“passChallenge”,false)=true;
让meetsKarmaThreshold=get(userDatabasePath).get(“karma”,1)>5;
返回IsownerAdmin&&meetsChallenge&&meetsKarmaThreshold;
}
匹配/products/{product}{
允许读取:如果为真;
允许写入:如果privilegedAccess();
}
匹配/类别/{category}{
允许读取:如果为真;
允许写入:如果privilegedAccess();
}
匹配/品牌/{brand}{
允许读、写:if privilegedAccess();
}
}
}
相同的条件授予对三个不同集合中的文档的写入权限

三元运算符 这是我们第一次引入
if/else
控制流,我们希望它能使规则更平滑、更强大

下面是一个使用三元运算符为写入指定复杂条件的示例

用户可以在两种情况下更新文档:首先,如果他们是管理员用户,则需要设置字段
overrideReason
approvedBy
。其次,如果他们不是管理员用户,则更新必须包括所有必需字段:

允许更新:如果是isadmin用户(request.auth.uid)?
request.resource.data.keys().toSet().hasAny([“overrideReason”,“approvedBy”]):
request.resource.data.keys().toSet().hasAll([“全部”、“所需”、“字段”])
在三元数之前可以表达这一点,但这是一个更简洁的表达