Firestore安全规则:允许用户仅创建Doc如果新Doc ID与用户ID相同

问题描述 投票:0回答:2

当用户第一次登录时,我还需要调用一个在我的firestore用户集合中创建文档的函数来存储他们的配置文件数据。使用Web SDK。

(我以前使用具有firebase功能的新用户触发事件,但是等待冷函数旋转太慢了)。

安全规则要求

需要确保用户只能在文档ID与其用户ID相同时创建文档(以防止用户创建其他文档)。需要确保此doc尚不存在。

尝试 - 在模拟器中工作,而不是IRL

这些测试通过模拟器,但不是IRL。

// Allow users to create a doc if the doc ID == their user id
allow create: if path("/databases/" + database + "/documents/users/" + request.auth.uid) == request.path;

要么

allow create: if /databases/$(database)/documents/users/$(request.auth.uid) == request.resource['__name__']

也试过这个(再次,在模拟器中工作,但不是IRL)

match /users/{userId} {
    // Allow users to read their own profile
    allow create: if request.auth.uid == userId;
}
firebase google-cloud-firestore firebase-security-rules
2个回答
2
投票

所以我想出了如何以解决方法的方式做到这一点。我还有一些额外的写入/更新条件,阻止用户更改其权限级别。这是出于某种原因,防止任何“创造”发生。所以我不得不在create和write / update规则中镜像相同的条件。出于某种原因,这是必要的。

This new rule structure accomplishes the following

第一部分,用于创建规则

  • 允许仅经过身份验证的用户仅在“users”集合中创建文档(在用户设置过程中,将使用与其用户ID相同的ID自动创建文档)。
  • 不允许创建包含“admin”字段的文档,这表明他们正试图获得管理员访问权限。
  • 似乎无法在创建期间验证文档的ID,因此下面还有其他写入/更新规则

第二部分 - 读取,更新,写入

  • 允许用户只读取/写入/更新与其用户ID具有相同ID的文档(用户尝试创建具有除用户ID之外的ID的文档将失败,还可以防止用户通过操作来发送大量文档的垃圾邮件客户端JS请求。)
  • 不允许用户编写/更新其个人资料以包含“admin”字段

规则

service cloud.firestore {

      match /databases/{database}/documents {

        // Allow users to create documents in the user's collection
        match /users/{document=**} {
          allow create: if request.auth.uid != null &&
            !("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
        }

        // Allow users to read, write, update documents that have the same ID as their user id
        match /users/{userId} {   
            // Allow users to read their own profile (doc id same as user id)
          allow read: if request.auth.uid == userId;

          // Allow users to write / update their own profile as long as no "admin" field is trying to be added or created
          allow write, update: if request.auth.uid == userId &&
            !("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
        }
      }
    }

PS这根本不直观,所以如果有人有更好的解决方法,请发布。此外,我真的希望一旦firestore 1.0出来,它将带来一些规则和规则文档的巨大改进。


0
投票

有点晚了,但我设法调整你的一个可能的解决方案并让它工作:

allow create: if path("/databases/(default)/documents/users/" + request.auth.uid) == request.path;

只需用database替换(default)变量。是的,不是花哨的......

© www.soinside.com 2019 - 2024. All rights reserved.