如何保护电子邮件地址,但可以使用Firestore搜索电子邮件地址

时间:2019-01-14 02:04:27

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

我在该主题上找不到任何东西,所以去了。

我正在使用带有用户的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()

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

仅使用Firestore的一种解决方法是创建一个附加集合,如下所示:

每次创建用户时,设置一个以电子邮件地址为键的空文档

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

这些安全规则进行了解释:

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

在实践中

您将拥有一个搜索表单<input>,并将其定位为执行:

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

const docRef = await firestore().doc(`searchUsers/${searchVal}`)
const userExists = docRef.exists