Ограничение одновременных входов в систему авторизованным пользователем в Firebase

Я искал и играл с Firebase, и я нашел это действительно интересным.

До сих пор я пробовал некоторые простые настройки политики аутентификации и безопасности, но теперь у меня есть проблема, которая, похоже, не описана в документации, и я не смог ничего найти в Google или здесь.

Проблема в том, что я не могу найти способ ограничить количество одновременных входов в систему для каждого адреса электронной почты/пароля.

Я хотел бы иметь вариант, при котором платные клиенты могут входить только с 1 IP-адреса за раз. Другими словами, я не хочу, чтобы люди могли приобрести учетную запись, а затем поделиться ею с друзьями и семьей, а затем все одновременно подключиться к системе, используя одни и те же учетные данные.

Заранее спасибо.


person Reza    schedule 03.11.2013    source источник


Ответы (1)


Вы будете контролировать доступ, записывая путь в Firebase всякий раз, когда пользователь входит в систему. Затем вы можете проверить этот путь, чтобы убедиться, что в каждый момент времени существует только один пользователь:

  • записывать значение пути каждый раз, когда пользователь входит в систему (например, logged_in_users/$user_id)
  • используйте onDisconnect(), чтобы удалить это значение при отключении пользователя.
  • проверьте этот путь на наличие значения при дополнительной попытке входа в систему
  • показать ошибку, если значение существует или разрешить вход, если нет

Это заботится о части UX. Чтобы защитить его от эксплойтов, вы воспользуетесь всеобъемлющими правилами безопасности Firebase:

  • создавать собственные токены аутентификации, используя индивидуальную стратегию входа
  • включить IP-адрес как часть данных внутри токена
  • отклонить попытки входа в систему, если logged_in_users/$user_id установлен на другой IP-адрес
  • написать правила безопасности, чтобы предотвратить чтение/запись с других IP-адресов

Предполагая, что вы сгенерировали токены, содержащие IP-адрес, ваши правила безопасности могут выглядеть примерно так:

".read": "root.child('logged_in_users/'+auth.uid).val() === auth.ip_address"
person Kato    schedule 03.11.2013
comment
Спасибо за ответ. В первой части вашего ответа в документе говорится: «Обратите внимание, что операции отключения запускаются только один раз». Если клиент отключается, а затем снова подключается, операции отключения необходимо будет инициировать снова. Кроме того, что произойдет, если пользователь просто закроет вкладку браузера или потеряет подключение к Интернету (мобильные сети и т. д.), тогда пользователь не будет отображаться в сети на неопределенный срок? - person Reza; 04.11.2013
comment
Что касается второй части решения, меня смущает auth.ip_address и недокументированная функция, потому что я ничего здесь не вижу firebase.com/docs/security/rule-expressions/auth.html или это просто значение, которое мы предоставляем через пользовательский логин как для идентификатора, так и для ip_адреса? В случае, если мы предоставляем оба, условие всегда будет истинным. - person Reza; 04.11.2013
comment
onDisconnect управляется сервером, поэтому каждый раз, когда клиент теряет соединение, он срабатывает, независимо от того, как клиент отключается. Когда клиент повторно подключается, вам нужно будет восстановить onDisconnect (в идеале это будет частью записи записи logged_in_users). Auth.ip_address представляет собой то, что вы можете добавить в собственный токен, созданный вами самостоятельно, см. пользовательские документы для входа, указанные в списках. Ваше здоровье. - person Kato; 04.11.2013
comment
это пользовательский логин, мы предоставляем значение как для id, так и для ip_address, поэтому при любой попытке входа в систему .read: root.child('logged_in_users/'+auth.id).val() === auth.ip_address будет действительным. Это правило безопасности похоже на .read: true == ture - person Reza; 05.11.2013
comment
По поводу onDisconnect. Как javascript, определенный на стороне клиента, запускается на стороне сервера? Если нет документированного способа определить событие на стороне сервера, которое также не работает для отключения сети или закрытия вкладок. - person Reza; 05.11.2013
comment
При вызове onDisconnect выполняемая операция отправляется на сервер. Когда клиент отключается, сервер замечает и инициирует действие. - person Anant; 08.11.2013