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

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

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

4 ответов



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


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

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

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

вот один подход для разрешения входа с несколькими поставщиками, использующими 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 и т. д. ID пользователя под / пользователи / $userid / (facebook-id / twitter-id / etc-id).

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

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


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

образец хранилища данных:

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.... the userMappings'пользователей укажет на главный счет в пользователи. Поэтому после входа в Facebook или Twitter мы можем посмотреть основную учетную запись пользователя. В пользователи мы храним список userMapping, который может получить доступ к своим данным.

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


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


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

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

Образец Хранилища Данных:

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