firestore“读取”和“列出”安全规则有什么区别?

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

在 Firestore 访问规则中使用

allow list;
allow read;
有什么区别?更具体地说,如果我只允许
list
而不是
read
津贴,我的数据会获得哪些额外保护?

在我看来,read 和 list 提供了相同的安全性,唯一的区别是

list
使得合法访问单个对象变得更加麻烦。毕竟,不良行为者可以简单地列出对象,然后读取其完整内容。如果他知道该对象的 ID,他可以简单地将其作为搜索项包含在内。

// The scopes collection is restricted to only allow 'list' requests.
// The scopes collection contains a 'postPhoto' document

// The following request will fail with an insufficient permission error, as expected
await db
  .collection(`/auth/${client}/scopes`)
  .doc('postPhoto')
  .get()
  .then(doc => console.log(doc.id, doc.data()))
  .catch(e => console.error(e))

// But this request will succeed, and it is in effect the same as the previous
await db
  .collection(`/auth/${client}/scopes`)
  .where(firebase.firestore.FieldPath.documentId(), '==', 'postPhoto')
  .get()
  .then(col => col.forEach(doc => console.log(doc.id, doc.data())))
  .catch(e => console.error(e))

我希望

list
访问权限只允许您查看文档的存在,但看不到它们的内容。但既然
list
显然也允许您访问底层文档数据,为什么不直接使用
read
呢?

firebase google-cloud-platform google-cloud-firestore firebase-security
3个回答
15
投票

实际上

list
read
的具体情况,如 文档中所述:

在某些情况下,将读取分解并将写入更多内容很有用 精细化操作。例如,...您可能希望允许单个文档读取但拒绝大型查询。

read规则可以分解为get和list


更具体地说,我们采用以下安全规则:

service cloud.firestore {
    match /databases/{database}/documents {
      match /col1/{docId=**} {
          allow list: if request.auth.uid != null;
      }   
      match /col2/{docId=**} {
          allow get: if request.auth.uid != null;
      }
  }
}

以下查询将起作用:

firebase.firestore().collection("col1").get()

虽然这个不起作用:

firebase.firestore().collection("col2").get()

现在,让我们假设每个集合都有一个 id 为“1”的文档。

以下查询将起作用:

firebase.firestore().collection("col2").doc("1").get()

虽然这个不起作用:

firebase.firestore().collection("col1").doc("1").get()

最后,如果您按如下方式更改规则,使用

read
,以上所有查询都将起作用!

service cloud.firestore {
    match /databases/{database}/documents {
      match /col1/{docId=**} {
          allow read: if request.auth.uid != null;
      }   
      match /col2/{docId=**} {
          allow read: if request.auth.uid != null;
      }
  }
}

0
投票

来自 Firebase 文档

read
规则可以分为
get
list
,而
write
规则可以分为
create
update
delete

write
规则定义非常清晰,
get
list
之间的区别如下:

  • get 规则将单个文档的检索限制为公共文档或用户创作的文档。
  • list 规则应用与 get 相同的限制,但适用于查询。它还检查查询限制,然后拒绝任何没有限制或限制大于 10 的查询。

(来自 安全查询数据 - Firebase 文档

在编写规则时请注意,

read
分为
get
list
- 因此它可以做任何它们组合起来可以做的事情。

从你的问题来看,

在我看来,read 和 list 提供了相同的安全性,唯一的区别是 list 使得合法访问单个对象变得更加麻烦。

list
用于安全地查询集合,当您从客户端调用
collection()
方法时会被触发。
get
另一方面,当您调用从
doc()
方法接收数据时。

毕竟,不良行为者可以简单地列出对象,然后读取其完整内容。如果他知道该对象的 ID,他可以简单地将其作为搜索项包含在内。

是的,但另一方面,

get
可用于防止集合列表查询。 Firebase 团队使用 list 和 get 的更好原因似乎是为了更轻松地编写查询,而不是改变安全功能的方式。 (到目前为止,没有办法限制基于 where 子句的查询,否则它可以在您的场景中用于保护。)


0
投票

通常,您永远不会同时使用

read
list
,因为
read
始终会覆盖
list
get

什么是

get

阅读您已经拥有文档 ID 的单个文档。

userCollection.doc(uid).snapshots()

什么是

list

使用

where

查询多个文档
userCollection.where('email', isEqualTo: email).snapshots()

什么时候使用

list
而不是
read

我想让客户端获取他们已经知道的用户的详细信息

uid
就像当他们是聊天组的一部分并且他们想要查看每个参与者的详细信息但不希望客户端运行查询时获取许多用户文档。 我会用这样的东西

allow get : if isAuthenticated();
allow list :  if false;
© www.soinside.com 2019 - 2024. All rights reserved.