Как я могу войти с несколькими социальными службами с помощью Firebase?

Я хочу, чтобы пользователи могли проходить проверку подлинности в моем приложении Firebase, используя несколько различных поставщиков аутентификации, таких как Facebook, Twitter или Github. После аутентификации я хочу, чтобы пользователи имели доступ к одной и той же учетной записи, независимо от того, какой метод аутентификации они использовали.

Другими словами, я хочу объединить несколько методов аутентификации в одну учетную запись в моем приложении. Как я могу сделать это в приложении Firebase?

4 ответа

Решение

Обновление (20160521): Firebase только что выпустила серьезное обновление для своего продукта Firebase Authentication, которое теперь позволяет одному пользователю связывать учетные записи от различных поддерживаемых поставщиков. Чтобы узнать больше об этой функции, прочитайте документацию для iOS, Web и Android. Ответ ниже оставлен по историческим причинам.


Базовая служба Firebase предоставляет несколько способов аутентификации: https://www.firebase.com/docs/security/authentication.html

По своей сути Firebase использует безопасные токены JWT для аутентификации. Все, что приводит к производству токена JWT (например, использование библиотеки JWT на вашем собственном сервере), будет работать для аутентификации ваших пользователей в Firebase, так что вы будете иметь полный контроль над процессом аутентификации.

Firebase предоставляет сервис под названием Firebase Simple Login, который является одним из способов генерирования этих токенов (это обеспечивает нашу авторизацию в Facebook, Twitter и т. Д.). Он предназначен для общих сценариев аутентификации, поэтому вы можете быстро приступить к работе без сервера, но это не единственный способ аутентификации и не является всеобъемлющим решением.

Вот один подход для разрешения входа в систему с несколькими провайдерами, использующими Firebase Simple Login:

  1. Сохраните один канонический идентификатор пользователя для каждого пользователя и сопоставление для каждого конкретного поставщика идентификатора с этим одним каноническим идентификатором.
  2. Обновите свои правила безопасности, чтобы они соответствовали любым учетным данным в данной учетной записи пользователя, а не одному.

На практике правила безопасности могут выглядеть следующим образом, при условии, что вы хотите включить аутентификацию Twitter и Facebook (или позволить пользователю создать учетную запись с одной, а затем добавить другую):

{
  "users": {
    "$userid": {
      // Require the user to be logged in, and make sure their current credentials
      // match at least one of the credentials listed below, unless we're creating
      // a new account from scratch.
      ".write": "auth != null && 
        (data.val() === null || 
        (auth.provider === 'facebook' && auth.id === data.child('facebook/id').val() || 
        (auth.provider === 'twitter' && auth.id === data.child('twitter/id').val()))"
    }
  },
  "user-mappings": {
    // Only allow users to read the user id mapping for their own account.
    "facebook": {
      "$fbuid": {
        ".read": "auth != null && auth.provider === 'facebook' && auth.id === $fbuid",
        ".write": "auth != null && 
          (data.val() == null || 
          root.child('users').child(data.val()).child('facebook-id').val() == auth.id)"
      }
    },
    "twitter": {
      "$twuid": {
        ".read": "auth != null && auth.provider === 'twitter' && auth.id === $twuid",
        ".write": "auth != null && 
          (data.val() == null || 
          root.child('users').child(data.val()).child('twitter-id').val() == auth.id)"
      }
    }
  }
}

В этом примере вы сохраняете один глобальный идентификатор пользователя (который может быть любым по вашему выбору) и поддерживаете сопоставление механизмов аутентификации Facebook, Twitter и т. Д. С основной записью пользователя. После входа в систему для каждого пользователя вы извлекаете основную запись пользователя из сопоставлений пользователей и используете этот идентификатор в качестве основного хранилища пользовательских данных и действий. Вышеприведенное также ограничивает и проверяет данные в сопоставлениях пользователей, так что они могут быть записаны только соответствующим пользователем, который уже имеет такой же идентификатор пользователя Facebook, Twitter и т. Д. В /users/$userid/(facebook-id|twitter) -id | и т.д.-идентификатор).

Этот метод позволит вам быстро начать работу. Однако, если у вас сложный вариант использования и вы хотите полностью контролировать процесс аутентификации, вы можете запустить свой собственный код аутентификации на ваших собственных серверах. Есть много полезных библиотек с открытым исходным кодом, которые вы можете использовать для этого, например, Everyauth и Passport.

Вы также можете пройти аутентификацию, используя сторонних поставщиков аутентификации. Например, вы можете использовать Singly, который имеет огромное разнообразие встроенных функций без необходимости писать какой-либо код на стороне сервера.

Я знаю, что этот пост существует месяцами, но когда я столкнулся с этой проблемой, мне потребовалось много времени, чтобы сделать код более гибким. Основываясь на коде Эндрю выше, я немного подправил код.

Пример хранилища данных:

userMappings
|---facebook:777
|   |---user:"123"
|---twitter:888
    |---user:"123"
users
|---123
    |---userMappings
        |---facebook: "facebook:777"
        |---twitter: "twitter:888"

Правила безопасности:

"userMappings": {
  "$login_id": {
    ".read": "$login_id === auth.uid",
    ".write": "auth!== null && (data.val() === null || $login_id === auth.uid)"
  }
},

"users": {
  "$user_id": {
    ".read": "data.child('userMappings/'+auth.provider).val()===auth.uid",
    ".write": "auth!= null && (data.val() === null || data.child('userMappings/'+auth.provider).val()===auth.uid)"
  }
}

Таким образом, userMappings по-прежнему является первой информацией, которую мы ищем при входе через Facebook, Twitter.... пользователь userMappings будет указывать на главную учетную запись пользователей. Таким образом, после входа в систему через Facebook или Twitter, мы можем посмотреть основной аккаунт пользователя. В пользователях мы храним список userMapping, который может получить доступ к его данным.

При создании нового пользователя, мы должны сначала создать учетную запись в пользователях. Идентификатор пользователя в пользователях может быть любым, что мы хотим. Это гибко, потому что мы можем предоставить больше методов входа, таких как Google, Github, без добавления дополнительных правил безопасности.

Я только что создал angularfire decorator, чтобы справиться с этим для нас: angularfire-multi-auth

Я потратил довольно много времени на размышления о хорошем решении, и ИМХО возможность зарегистрироваться у любого провайдера просто сбивает с толку. В своем интерфейсе я всегда запрашиваю регистрацию по электронной почте, поэтому, когда пользователь, входящий в систему с помощью facebook и google+, будет зарегистрирован как тот же пользователь, когда он сообщит свою электронную почту.

Таким образом, образцы данных, предложенные Kuma, не должны дублировать пользовательские приложения.

Пример хранилища данных:

userMappings
|---facebook:777
|   |---user:"123"
|---twitter:888
    |---user:"123"
users
|---123
    |---user data
Другие вопросы по тегам