【问题标题】:Cloud Firestore Security Rules - only allow write to specific key in documentCloud Firestore 安全规则 - 仅允许写入文档中的特定密钥
【发布时间】:2019-11-02 16:48:28
【问题描述】:

我目前正在使用 Firestore 数据库为我的应用程序编写一些规则。 目前每个人都可以读取数据,经过身份验证的用户可以写入。

  match /quizzes/{quizId} {
    allow read; 
    allow write: if request.auth != null;
  }

这很好用,但我也希望未经身份验证的用户只写入文档中的特定键。

文档的示例内容:

{
  title: 'title',
  plays: 12,
  playedBy: [//Filled with user id's],
  ...
}

是否有任何方法可以限制未经身份验证的用户只能对 playBy 数组而不是该文档的其他键具有写访问权限?

【问题讨论】:

    标签: firebase google-cloud-firestore firebase-security


    【解决方案1】:

    在较早的答案(我相信是 2019 年末)之后,Firebase 引入了Map.diff

    类似:

    match /quizzes/{quizId} {
        allow read; 
        allow write: if request.auth != null ||
          request.resource.data.diff(resource.data).affectedKeys() == ["playedBy"].toSet()
      }
    

    可以看到我使用它的测试代码here

    【讨论】:

    • 我不确定为什么这个答案被否决了——这正是我想要的。谢谢,@akauppi。
    【解决方案2】:

    当然。但是如果你有很多领域,它可能会变得有点复杂。

    让我们从最简单的例子开始。这样的事情允许未经身份验证的用户编写playedBy,只要这是文档中的唯一字段:

    if request.auth != null || request.resource.data.keys().hasOnly(['playedBy'])
    

    如果未经身份验证的用户正在创建新文档或更新现有文档,则此方法有效。但一旦文档包含更多字段,它就会停止,因为request.resource.data 包含写入成功后文档将具有的所有字段。

    因此,更好的选择是检查是否只有playedBy 被修改,并且所有其他字段的值是否与以前相同。棘手的一点是处理不存在的字段,我通常使用一些辅助函数来处理:

    function isUnmodified(key) {
      return request.resource.data[key] == resource.data[key]
    }
    function isNotExisting(key) {
      return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
    }
    

    然后:

    if request.auth != null &&
      request.resource.data.keys().hasOnly(['title', 'plays', 'playedBy']) &&
      isUnmodified('title') && 
      isUnmodified('plays')
    

    确切的规则可能有点偏离,但我希望这足以让您自己完成。

    【讨论】:

    • 谢谢@Frank van Puffelen。我会试试看的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 2018-10-01
    • 2019-03-03
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    相关资源
    最近更新 更多