Comment puis-je me connecter avec plusieurs services sociaux avec Firebase?

Je souhaite que les utilisateurs puissent s'authentifier auprès de mon application Firebase en utilisant plusieurs fournisseurs d'authentification différents, tels que Facebook, Twitter ou Github. Une fois authentifié, je veux que les utilisateurs aient accès au même compte, quelle que soit la méthode auth utilisée.

En d'autres termes, je veux fusionner plusieurs méthodes d'authentification en un seul compte dans mon application. Comment puis-je faire cela dans une application Firebase?

54
demandé sur Andrew Lee 2013-03-01 04:06:42

4 réponses


Mise À Jour (20160521): Firebase vient de publier une mise à jour majeure de son produit Firebase Authentication, qui permet désormais à un seul utilisateur de lier les comptes des différents fournisseurs pris en charge. Pour en savoir plus sur cette fonctionnalité, consultez la documentation de iOS, Web et Android. La réponse ci-dessous est laissée pour des raisons historiques.


Le service core Firebase fournit plusieurs méthodes pour Authentication: https://www.firebase.com/docs/security/authentication.html

À la base, Firebase utilise des jetons JWT sécurisés pour l'authentification. Tout ce qui entraîne la production d'un jeton JWT (comme l'utilisation d'une bibliothèque JWT sur votre propre serveur) fonctionnera pour authentifier vos utilisateurs à Firebase, de sorte que vous avez un contrôle complet sur le processus d'authentification.

Firebase fournit un service appelé Firebase simple Login qui est un moyen de générer ces jetons (ceci fournit notre Facebook, Twitter, etc auth). Il est destiné aux scénarios d'authentification courants afin que vous puissiez démarrer rapidement sans serveur, mais ce n'est pas le seul moyen d'authentifier, et n'est pas destiné à être une solution complète. 

Voici une approche pour permettre la connexion avec plusieurs fournisseurs en utilisant Firebase simple Login:

  1. stocke un identifiant d'utilisateur canonique pour chaque utilisateur, et un mappage pour chaque identifiant spécifique du fournisseur à celui-ci canonique ID.
  2. mettez à jour vos règles de sécurité pour qu'elles correspondent à compte d'utilisateur donné, au lieu d'un seul.

En pratique, les règles de sécurité peuvent ressembler à ceci, en supposant que vous souhaitez activer L'authentification Twitter et Facebook (ou permettre à un utilisateur de créer un compte avec l'un, puis d'ajouter l'autre):

{
  "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)"
      }
    }
  }
}

Dans cet exemple, vous stockez un identifiant utilisateur global (qui peut être n'importe quoi de votre choix) et maintenez le mappage entre Facebook, Twitter, etc. mécanismes d'authentification à l'enregistrement de l'utilisateur principal. Lors de la connexion pour chaque utilisateur, vous récupérerez l'enregistrement utilisateur principal à partir des mappages utilisateur et utiliserez cet id comme magasin principal de données et d'actions utilisateur. Ce qui précède restreint et valide également les données dans les mappages utilisateur afin qu'elles ne puissent être écrites que par l'utilisateur approprié qui a déjà le même Facebook, Twitter, etc. id utilisateur dans /utilisateurs/$userid/(facebook-id|twitter-id|etc-id).

Cette méthode vous permettra d'être rapidement opérationnel. Toutefois, si vous avez un complexe d'utilisation et d'voulez un contrôle complet sur l'authentification de l'expérience, vous pouvez exécuter votre propre auth code sur vos propres serveurs. Il existe de nombreuses bibliothèques Open source utiles que vous pouvez utiliser pour ce faire, telles que everyauth et passport.

Vous pouvez également vous authentifier en utilisant des fournisseurs d'authentification tiers. Par exemple, vous pouvez utiliser Singly , qui a une grande variété d'intégrations prêtes à l'emploi sans que vous ayez besoin d'écrire un côté serveur code.

55
répondu Andrew Lee 2016-05-22 00:07:07

Je sais que ce post existe depuis des mois mais quand j'ai fait face à ce problème, il m'a fallu beaucoup de temps pour rendre le code plus flexible. Sur la base du code Andrew ci-dessus, j'ai un peu modifié le code.

Exemple de banque de données:

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

règles de Sécurité:

"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)"
  }
}

Donc userMappings {[6] } est toujours la première information que nous recherchons lors de la connexion par Facebook, Twitter.... le userMappings' utilisateur le compte principal dans utilisateurs. Donc, après la connexion par Facebook ou Twitter, nous pouvons rechercher le compte utilisateur principal. Dans users nous conservons la liste des userMapping qui peuvent accéder à ses données.

Lors de la création d'un nouvel utilisateur, nous devons d'abord créer un compte dans users. L'id de l'utilisateur dans users pourrait être tout ce que nous voulons. Ceci est flexible car nous pouvons fournir plus de méthode de connexion comme Google, Github sans ajouter plus de règle de sécurité.

16
répondu Kuma 2014-10-30 12:51:33

Je viens de créer un décorateur angularfire pour gérer cela pour nous: angularfire-multi-auth

2
répondu Douglas Correa 2015-09-30 18:33:54

J'ai passé un certain temps à réfléchir à une bonne solution, et à mon humble avis, pouvoir s'inscrire auprès de n'importe quel fournisseur est juste déroutant. Dans mon frontal, je demande toujours une inscription par e-mail, donc un utilisateur se connectant avec facebook et google+, par exemple, serait connecté en tant que même utilisateur lorsqu'il informe son e-mail.

De cette façon, les exemples de données proposés par Kuma n'ont pas besoin de dupliquer les userMappings.

Exemple De Banque De Données:

userMappings
|---facebook:777
|   |---user:"123"
|---twitter:888
    |---user:"123"
users
|---123
    |---user data
0
répondu Jp_ 2016-05-10 17:36:00