web-dev-qa-db-fra.com

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 accès 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?

56
Andrew Lee

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


Le service principal de Firebase propose 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 se traduit par 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, afin que vous ayez 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 (cela fournit notre authentification Facebook, Twitter, etc.). Il est destiné aux scénarios d'authentification courants afin que vous puissiez être opérationnel rapidement sans serveur, mais ce n'est pas le seul moyen de s'authentifier et n'est pas destiné à être une solution complète.

Voici une approche pour autoriser la connexion avec plusieurs fournisseurs à l'aide de Firebase Simple Login:

  1. Stockez un identifiant utilisateur canonique pour chaque utilisateur et un mappage pour chaque identifiant spécifique au fournisseur avec cet identifiant canonique.
  2. Mettez à jour vos règles de sécurité pour qu'elles correspondent à l'une des informations d'identification d'un compte d'utilisateur donné, au lieu d'un seul.

Dans la pratique, les règles de sécurité peuvent ressembler à ceci, en supposant que vous souhaitiez activer à la fois l'authentification Twitter et Facebook (ou autoriser un utilisateur à créer un compte avec l'un et ensuite 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 les mécanismes d'authentification Facebook, Twitter, etc. sur l'enregistrement utilisateur principal. Lors de la connexion de chaque utilisateur, vous récupérerez l'enregistrement d'utilisateur principal à partir des mappages d'utilisateurs 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 d'utilisateurs afin qu'elles ne puissent être écrites que par l'utilisateur approprié qui a déjà le même identifiant d'utilisateur Facebook, Twitter, etc. sous/users/$ userid/(facebook-id | Twitter -id | etc-id).

Cette méthode vous permettra d'être opérationnel rapidement. Cependant, si vous avez un cas d'utilisation compliqué et souhaitez 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 ce faire, telles que everyauth et passport .

Vous pouvez également vous authentifier à l'aide de 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 à écrire de code côté serveur.

56
Andrew Lee

Je sais que ce message existe depuis des mois, mais lorsque j'ai rencontré 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 légèrement modifié le code.

Exemple de magasin 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)"
  }
}

Alors userMappings est toujours la première information que nous recherchons lorsque vous vous connectez par Facebook, Twitter .... the userMappings ' utilisateur pointera vers le compte principal utilisateurs. Ainsi, après la connexion par Facebook ou Twitter, nous pouvons rechercher le compte utilisateur principal. Dans utilisateurs nous conservons la liste des utilisateurs qui peuvent accéder à ses données.

Lorsque vous créez un nouvel utilisateur, nous devons créer un compte dans utilisateurs première. L'ID de l'utilisateur dans utilisateurs pourrait être tout ce que nous voulons. C'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
Kuma

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

2
Douglas Correa

J'ai passé pas mal de temps à réfléchir à une bonne solution, et à mon humble avis, pouvoir m'inscrire auprès de n'importe quel fournisseur est tout simplement déroutant. Dans mon front-end, je demande toujours un enregistrement par e-mail, donc un utilisateur qui se connecte avec facebook et google +, par exemple, serait enregistré comme le même utilisateur lorsqu'il informera 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 magasin de données:

userMappings
|---facebook:777
|   |---user:"123"
|---Twitter:888
    |---user:"123"
users
|---123
    |---user data
0
Jp_