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 à l’aide de plusieurs fournisseurs d’authentification différents, tels que Facebook, Twitter ou Github. Une fois authentifié, je souhaite que les utilisateurs aient access au même compte, quelle que soit la méthode d’authentification utilisée.

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


    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 des comptes provenant de différents fournisseurs pris en charge. Pour en savoir plus sur cette fonctionnalité, lisez la documentation pour iOS , Web et Android . La réponse ci-dessous est laissée pour des raisons historiques.


    Le service Firebase de base fournit plusieurs méthodes d’authentification: https://www.firebase.com/docs/security/authentication.html

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

    Firebase fournit un service appelé Firebase Simple Login qui permet de générer ces jetons (ceci fournit notre authentification Facebook, Twitter, etc.). Il est conçu pour les scénarios d’authentification courants afin que vous puissiez être rapidement opérationnel sans serveur, mais ce n’est pas la seule manière de vous authentifier et ne constitue pas une solution complète.

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

    1. Stocker un identifiant d’utilisateur canonique pour chaque utilisateur et un mappage pour chaque identificateur spécifique à un fournisseur à cet identifiant canonique.
    2. Mettez à jour vos règles de sécurité pour qu’elles correspondent à toutes les informations d’identification d’un compte d’utilisateur donné, au lieu d’un seul.

    En pratique, les règles de sécurité peuvent ressembler à ceci, en supposant que vous souhaitiez activer l’authentification à la fois Twitter et Facebook (ou permettre à un utilisateur de créer un compte avec l’un puis 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 d’utilisateur global (qui peut être n’importe lequel) et maintenez la correspondance entre les mécanismes d’authentification Facebook, Twitter, etc. Lors de la connexion pour chaque utilisateur, vous récupérerez l’enregistrement utilisateur principal à partir des mappages utilisateur et utiliserez cet identifiant 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’il ne puisse être écrit que par le bon utilisateur qui possède déjà le même identifiant Facebook, Twitter, etc. sous / users / $ userid / (facebook-id | twitter -id | etc-id).

    Cette méthode vous permettra de démarrer rapidement. Cependant, si votre cas d’utilisation est compliqué et que vous souhaitez avoir un contrôle complet sur l’expérience d’authentification, vous pouvez exécuter votre propre code d’authentification sur vos propres serveurs . Il existe de nombreuses bibliothèques open source utiles que vous pouvez utiliser pour cela, telles que everyauth et passport .

    Vous pouvez également vous authentifier à l’aide de fournisseurs d’authentification tiers. Par exemple, vous pouvez utiliser Singly , qui propose une grande variété d’intégrations prêtes à l’ emploi sans avoir à écrire de code côté serveur.

    Je sais que ce post existe depuis des mois mais quand j’ai rencontré ce problème, il m’a fallu beaucoup de temps pour rendre le code plus flexible. Base sur le code Andrew ci-dessus, j’ai légèrement modifié le code.

    Magasin de données échantillon:

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

    Ainsi, userMappings est toujours la première information que nous recherchons lors de la connexion par Facebook, Twitter… L’ utilisateur de userMappings pointera vers le compte principal des utilisateurs . Ainsi, une fois connecté par Facebook ou Twitter, nous pouvons rechercher le compte utilisateur principal. Dans les utilisateurs, nous conservons une liste de userMapping pouvant accéder à ses données.

    Lorsque vous créez un nouvel utilisateur, vous devez d’abord créer un compte chez les utilisateurs . L’identifiant pour l’utilisateur dans les utilisateurs pourrait être tout ce que nous voulons. Ceci est flexible car nous pouvons fournir plus de méthode de connexion comme Google, Github sans append de règles de sécurité supplémentaires.

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

    J’ai passé beaucoup de temps à réfléchir à une bonne solution, et IMHO pour pouvoir s’enregistrer auprès de n’importe quel fournisseur est simplement déroutant. Dans mon front-end, je demande toujours un enregistrement par e-mail. Ainsi, un utilisateur qui se connecte avec facebook et google +, par exemple, sera enregistré en tant que même utilisateur lorsqu’il informera son courrier électronique.

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

    Exemple de magasin de données:

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