Как защитить адреса электронной почты, но сделать их доступными для поиска с помощью Firestore - PullRequest
0 голосов
/ 14 января 2019

Я не смог найти ничего по теме, так что вот так.

Я создаю приложение с базой данных 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 голосов
/ 14 января 2019

Существует обходной путь без использования облачных функций

Один из способов решения этой проблемы с использованием только 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;
}

Эти правила безопасности объяснили:

  • allow create rule: "разрешать пользователям создавать документы только со своим адресом электронной почты"
  • allow list rule: «Запретить пользователям получать все эти письма»
    • с .collection('searchUsers').get()
  • allow get rule: «вы можете запросить один документ с адресом электронной почты в качестве ключа для проверки существования»
    • с .doc('searchUsers/user@gmail.com').get()

На практике

У вас будет поисковая форма <input>, цель которой - выполнить:

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

const docRef = await firestore().doc(`searchUsers/${searchVal}`).get()
const userExists = docRef.exists
0 голосов
/ 14 января 2019

Кажется, вы не можете применить это с правилами безопасности, поэтому лучше всего было бы написать облачную функцию ( http или callable ), которая будет выполнять запрос безопасно и вернуть желаемый результат клиенту. Эта функция будет принимать адрес электронной почты в качестве входного аргумента и минимально выводить некоторое логическое значение, указывающее, существует ли пользователь.

...