【问题标题】:How to protect email addresses but make them searchable with Firestore如何保护电子邮件地址但使其可使用 Firestore 进行搜索
【发布时间】:2019-01-14 02:04:26
【问题描述】:

我找不到有关该主题的任何内容,所以就到这里。

我正在使用带有用户的 Firebase Cloud Firestore 数据库创建应用。

我的目标是“防止人们窃取所有电子邮件地址,但仍使它们可供搜索”

我的用户数据按用户保存,如下所示:

/users/{userId}

{
  email: 'user@gmail.com',
  displayName: 'James Liverstone'
}

我可以使用以下规则保护用户数据:

match /users/{userId} {
  allow write, read: if request.auth.uid == userId
                     && request.auth.uid != null;
}

但是,如果我想让某人可以通过电子邮件或显示名在我的应用中搜索朋友,该怎么办?

例如。

const searchVal = 'user@gmail.com' // search value from <input>

firebase.firestore().collection('users').where('email', '==', searchVal)

由于read 规则,这是不可能的。但是,如果我打开阅读以允许所有人,您可以像这样窃取我用户的所有电子邮件地址:

firebase.firestore().collection('users').get()

我怎样才能防止人们窃取所有电子邮件地址,但仍使其可搜索?

简而言之:

  • 允许:firebase.firestore().collection('users').where('email', '==', searchVal)
  • 阻止:firebase.firestore().collection('users').get()

【问题讨论】:

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


    【解决方案1】:

    您似乎无法通过安全规则强制执行此操作,因此您最好编写一个云函数(httpcallable)来安全地执行查询并将所需结果返回给客户端。此函数将电子邮件地址作为输入参数,并最少输出一些指示用户是否存在的布尔值。

    【讨论】:

      【解决方案2】:

      有一种不使用 Cloud Functions 的解决方法

      仅使用 firestore 的一种解决方法是创建一个额外的集合,如下所示:

      每次创建用户时,设置一个以邮箱为key的空文档

      const email = 'user@gmail.com' //get the email of the new user
      
      firestore().doc(`searchUsers/${email}`).set({})
      

      这样我们就有了一个名为 searchUsers 的集合,其中包含一堆以电子邮件地址为键的空文档。

      所需的安全规则:

      • 阻止用户收到所有这些电子邮件
        • .collection('searchUsers').get()
      • 允许检查单个电子邮件地址的存在
        • .doc('searchUsers/user@gmail.com').get()

      像这样设置安全规则:

      match /searchUsers/{value} {
        allow create: if request.auth != null
                      && value == request.auth.token.email;
        allow list: if false;
        allow get;
      }
      

      这些安全规则解释:

      • allow create 规则:“只允许用户使用自己的电子邮件地址创建文档”
      • allow list 规则:“阻止用户收到所有这些电子邮件”
        • .collection('searchUsers').get()
      • allow get 规则:“您可以以电子邮件为关键字查询单个文档以检查是否存在”
        • .doc('searchUsers/user@gmail.com').get()

      在实践中

      您将有一个搜索表单 &lt;input&gt; 并定位它来执行:

      const searchVal = 'user@gmail.com' // search value from <input>
      
      const docRef = await firestore().doc(`searchUsers/${searchVal}`).get()
      const userExists = docRef.exists
      

      【讨论】:

        猜你喜欢
        • 2020-05-11
        • 2014-02-20
        • 2020-12-04
        • 1970-01-01
        • 2019-12-31
        • 2021-06-17
        • 2014-07-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多