【问题标题】:Security rules for updates in FirestoreFirestore 中更新的安全规则
【发布时间】:2018-03-27 08:18:19
【问题描述】:

在实时数据库中,当对单个值调用更新时,如果未在请求中指定,安全规则将评估数据库中存在的值。

在 Firestore 中,我们必须为 Firestore resource.data 中已存在的数据或请求 request.resource.data 中的数据创建规则。

这导致您必须复制带有 or 条件的安全规则来检查当前数据,以便可以更新单个值。

构建安全规则以为一组数据值中的每一个指定一个条件,同时仍允许更新单个数据的最佳方法是什么?

match /subscriptions/{uid} {
    allow read: if request.auth.uid == uid;
    allow write: if request.auth.uid == uid                     
        && request.resource.data.keys().hasAll(['allowedTerminals', 'activeTerminals'])
        && request.resource.data.allowedTerminals is int && request.resource.data.allowedTerminals > 0
        && request.resource.data.activeTerminals is int;
}

鉴于此安全规则,当我最初提供 activeTerminalallowedTerminal 值时,我可以成功创建新订阅,但如果我想更新 activeTerminal 值,我必须提供 allowedTerminal 值作为好吧,否则更新将返回权限被拒绝错误。

【问题讨论】:

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


    【解决方案1】:

    实时数据库和 Firestore 之间的行为实际上非常相似:

    data == resource.data             // data in the database
    newData == request.resource.data  // data in the incoming request
    

    主要区别在于 Firestore 提供了精细操作:

    allow get, list; // same as allow read;
    allow create, update, delete; // same as allow write;
    

    您可能希望为createupdatedelete 分别制定规则:

    allow create: if isMyCustomObject(request.resource.data);
    allow update: if isUpdateToMyCustomObject(request.resource.data);
    allow delete: if ...
    

    您可以在the docs 中阅读有关此内容的更多信息(抱歉,这部分内容被推得太低了!)

    【讨论】:

    • 因此,在 Firestore 中,我们必须为每个操作编写单独的规则,即使我们想对值应用相同的规则。这似乎不是很干燥。我知道他们有希望提高性能以及在 Firestore 下查询多个字段的能力,但我不确定这是否超过了将注入应用程序的维护,特别是因为当权限被拒绝时,firebase 没有给出哪些规则失败的指示。我认为这是大型应用程序中的噩梦。
    • 在 Firestore 中,您可以为每个操作编写单独的规则。通常每个操作都有不同的授权要求,因此这是可取的。我相信您的观点更多,“虽然授权要求可能会发生变化,但我总是希望独立于这些要求来强制执行我的架构”,不是吗?类似于实时数据库中的“.validate”规则。
    • 正是迈克。似乎在 Firestore 中保留模式的唯一方法是始终传递您将存储的整个数据,而不是单个值。在那一点上,尽管我不确定 set 或 update 有何不同,除非您将它们用于权限而不是验证数据。
    • 我觉得这是一个疏忽。如果我有一个文档,其中存储了 20 个值,并且我想更新该文档中的单个值,我不应该传递所有文档值来更新单个值来强制执行模式。
    • createupdatedelete 从 SDK 角度和安全角度来看都是不同的操作。例如:创建可能包含几个必需的属性,而更新可能包含几个可选属性之一(而删除显然没有属性)。强制执行资源模式需要使用诸如 Open API 规范 (github.com/OAI/OpenAPI-Specification) 之类的东西,您必须在每个操作中为每个资源指定必填和可选字段,就像我们在这里所做的那样。
    猜你喜欢
    • 2020-06-19
    • 2019-01-09
    • 2019-01-15
    • 2019-06-17
    • 2018-10-19
    • 2019-07-05
    • 2021-07-12
    • 2021-09-09
    相关资源
    最近更新 更多