Firestore 规则:resource.data.keys() 不包含读取中的所有字段

2024-04-12

设置


我在 Firebase Firestore 中有一个集合,其中包含以下字段:

(["active" , "created" , "description" , "displayName" , "expires" , "image" , "type" , "uid" , "userName"])

where "expires"是可选的。

写入规则确保每个对象都遵循该形式并成功测试。

问题


当尝试从集合中读取时,我有一条规则,规定如下:

let seeUnexpired = !("expires" in resource.data.keys()) ||
resource.data.expires > request.time ||
request.auth.uid == resource.data.uid;

这禁止除作者之外的用户阅读过期的条目。然而,这条规则并不禁止读取。我正在使用带有精心策划的数据的本地模拟器进行测试,并且确信过期字段存在并且对于此测试来说已经过时。

Details


在尝试调试时,我发现导致规则失败的条件是!("expires" in resource.data.keys()).

运行测试debug(resource.data.keys())打印出这个对象到firestore-debug.log:

list_value {
  values {
    string_value: "active"
  }
}

where "active"仅在请求中使用此查询条件时显示:...collection('collection_name').where('active', '==', true).get().

这向我表明resource.data.keys()仅包含资源中引用的字段where关于读取请求的条款。这意味着请求可以通过简单地不在查询中包含“字段不得存在”规则来规避该规则。

Debug:

Mar 31, 2021 12:34:48 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
list_value {
  values {
    string_value: "active"
  }
}

Tests


Test:

await firestoreAdmin.collection(COLLECTIONS.items).doc(mockItem.id).update({active: true, expires: new Date('01 Jan 2000 00:00:00 GMT')});
const query = firestore.collection(COLLECTIONS.items).where('active', '==', true); //unAuthed firestore instance
await assertFails(query.get());

Rule:

function readItemRules() {
  let seeActive = resource.data.active == true || request.auth.uid == resource.data.uid;
  let seeUnexpired = !("expires" in resource.data.keys()) ||
  resource.data.expires > request.time ||
  request.auth.uid == resource.data.uid; TODO figure out expiration rules
  return seeActive && seeUnexpired;
}

Data: Firestore Emulator Data

问题


我对这个问题的理解是否准确,或者我是否遗漏了细节或语法怪癖?这种行为是故意的吗?如果是的话,我应该如何修改我的规则/数据以强制执行这种安全性?


我的发现是,对于读取规则,firestore 似乎只加载查询中提到的文档中的字段。这对于要求字段存在或匹配某些内容的规则很有意义,因为如果您不将其包含在查询中,它们肯定会失败(因为它们将针对未定义的内容进行测试)。它在这里不起作用,因为如果您从查询中省略它,无论如何它都会通过不存在规则,因为 firestore 在执行检查时从整个资源中省略了该字段。

我的解决方案只是添加另一个布尔字段“hasExpiration”,指示“expires”字段是否存在。我对这个解决方案有点不满意,因为它增加了复杂性并落在客户端/写入规则上以确保这些字段之间存在奇偶校验。

https://firebase.google.com/docs/firestore/security/rules-query#rules_are_not_filters https://firebase.google.com/docs/firestore/security/rules-query#rules_are_not_filters

https://firebase.google.com/docs/firestore/security/rules-struct#capsular_operations https://firebase.google.com/docs/firestore/security/rules-structure#granular_operations

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Firestore 规则:resource.data.keys() 不包含读取中的所有字段 的相关文章

随机推荐