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

时间:2019-07-29 11:22:34

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

在Firestore访问规则中使用allow list;allow read;有什么区别?更具体地说,如果我只允许list而不是read的津贴,我的数据将获得什么额外的保护?

在我看来,读取和列表提供相同的安全性,并且他唯一的不同是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

2 个答案:

答案 0 :(得分:2)

实际上listread的一种特殊情况,如documentation中所述:

  

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

     

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;
      }
  }
}

答案 1 :(得分:0)

来自Firebase Documentaion

read规则可以分为getlist,而write规则可以分为createupdate,和delete

write规则定义非常清楚,getlist之间的区别如下:

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

(来自Securely query data - Firebase Documentation

尽管编写规则要注意,read分为getlist,因此它可以将它们组合在一起的所有功能。

根据您的问题,

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

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

毕竟,一个坏演员可以简单地列出对象,然后读取它们的全部内容。而且,如果他知道对象的ID,则只需将其作为搜索项即可。

是的,不过,在另一方面,get可用于保护免受收藏夹列表查询的影响。 Firebase团队使用list and get似乎是一个更好的理由,是使其更容易编写查询,而不是更改安全功能。 (到目前为止,这里有isn't a way to limit query based on where clause,否则它可能已被用来保护您的情况。)