S'authentifier avec Firebase à l'aide de liens d'e-mail

Vous pouvez utiliser Firebase Authentication pour connecter un utilisateur en lui envoyant un e-mail contenant un lien sur lequel il peut cliquer pour se connecter. Au cours du processus, l'adresse e-mail de l'utilisateur est également validée.

Se connecter par e-mail présente de nombreux avantages :

  • Inscription et connexion fluides
  • Risque réduit de réutilisation de mots de passe dans les applications, ce qui peut compromettre la sécurité des mots de passe, même bien sélectionnés.
  • Capacité à authentifier un utilisateur tout en vérifiant qu'il est le propriétaire légitime d'une adresse e-mail.
  • Pour se connecter, un utilisateur n'a besoin que d'un compte de messagerie accessible. Il n'est pas nécessaire d'être propriétaire d'un numéro de téléphone ou d'un compte de réseau social.
  • Un utilisateur peut se connecter de manière sécurisée sans avoir à fournir (ni à mémoriser) de mot de passe, ce qui peut être pénible sur un appareil mobile.
  • Un utilisateur existant qui se connectait auparavant avec un identifiant d'adresse e-mail (mot de passe ou fédération) peut passer à la connexion avec l'adresse e-mail uniquement. Par exemple, un utilisateur qui a oublié son mot de passe peut toujours se connecter sans avoir à le réinitialiser.

Avant de commencer

  1. Si ce n'est pas déjà fait, suivez les étapes du guide de démarrage.

  2. Activez la connexion par lien e-mail pour votre projet Firebase.

    Pour connecter les utilisateurs via un lien e-mail, vous devez d'abord activer le fournisseur de messagerie et la méthode de connexion par lien e-mail pour votre projet Firebase :

    1. Dans la console Firebase, ouvrez la section Authentification.
    2. Dans l'onglet Mode de connexion, activez le fournisseur Adresse e-mail/Mot de passe. Notez que la connexion par e-mail/mot de passe doit être activée pour pouvoir utiliser la connexion par lien d'e-mail.
    3. Dans la même section, activez la méthode de connexion Lien envoyé par e-mail (connexion sans mot de passe).
    4. Cliquez sur Enregistrer.

Pour lancer le flux d'authentification, présentez une interface qui invite l'utilisateur à fournir son adresse e-mail, puis appelez sendSignInLinkToEmail() pour demander à Firebase d'envoyer le lien d'authentification à l'adresse e-mail de l'utilisateur.

  1. Créez l'objet ActionCodeSettings, qui fournit à Firebase des instructions sur la création du lien dans l'e-mail. Attribuez aux champs suivants les valeurs correspondantes :

    • url : lien profond à intégrer et état supplémentaire à transmettre. Le domaine du lien doit figurer sur la liste des domaines autorisés de la console Firebase. Pour y accéder, accédez à l'onglet "Mode de connexion" (Authentication -> Sign-in method). Le lien redirige l'utilisateur vers cette URL si l'application n'est pas installée sur son appareil et qu'elle n'a pas pu être installée.

    • androidPackageName et IOSBundleId : applications à utiliser lorsque le lien de connexion est ouvert sur un appareil Android ou iOS. Découvrez comment configurer Firebase Dynamic Links pour ouvrir des liens d'action par e-mail via des applications mobiles.

    • Définissez handleCodeInApp sur true. Contrairement aux autres actions par e-mail hors bande (réinitialisation du mot de passe et validation de l'adresse e-mail), l'opération de connexion doit toujours être effectuée dans l'application. En effet, à la fin du flux, l'utilisateur doit être connecté et son état d'authentification doit être conservé dans l'application.

    • dynamicLinkDomain: lorsque plusieurs domaines de liens dynamiques personnalisés sont définis pour un projet, indiquez celui à utiliser lorsque le lien doit être ouvert via une application mobile spécifiée (par exemple, example.page.link). Sinon, le premier domaine est automatiquement sélectionné.

    var acs = ActionCodeSettings(
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true
        handleCodeInApp: true,
        iOSBundleId: 'com.example.ios',
        androidPackageName: 'com.example.android',
        // installIfNotAvailable
        androidInstallApp: true,
        // minimumVersion
        androidMinimumVersion: '12');
    
  2. Demandez à l'utilisateur de vous fournir son adresse e-mail.

  3. Envoyez le lien d'authentification à l'adresse e-mail de l'utilisateur et enregistrez-la au cas où l'utilisateur termine la connexion par e-mail sur le même appareil.

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLinkToEmail(
            email: emailAuth, actionCodeSettings: acs)
        .catchError((onError) => print('Error sending email verification $onError'))
        .then((value) => print('Successfully sent email verification'));
    });
    

Problèmes de sécurité

Pour éviter qu'un lien de connexion ne soit utilisé pour se connecter en tant qu'utilisateur non autorisé ou sur un appareil non autorisé, Firebase Authentication exige que l'adresse e-mail de l'utilisateur soit fournie lors du parcours de connexion. Pour que la connexion aboutisse, cette adresse e-mail doit correspondre à celle à laquelle le lien de connexion a été envoyé à l'origine.

Vous pouvez simplifier ce flux pour les utilisateurs qui ouvrent le lien de connexion sur le même appareil qu'ils ont demandé en stockant leur adresse e-mail localement (par exemple, à l'aide de SharedPreferences) lorsque vous envoyez l'e-mail de connexion. Utilisez ensuite cette adresse pour finaliser le parcours. Ne transmettez pas l'adresse e-mail de l'utilisateur dans les paramètres d'URL de redirection et ne la réutilisez pas, car cela pourrait permettre des injections de session.

Une fois la connexion terminée, tout mécanisme de connexion précédent non validé sera supprimé de l'utilisateur et toutes les sessions existantes seront invalidées. Par exemple, si quelqu'un a déjà créé un compte non validé avec les mêmes adresse e-mail et mot de passe, le mot de passe de l'utilisateur sera supprimé pour empêcher l'emprunteur qui a revendiqué la propriété et créé ce compte non validé de se reconnecter avec l'adresse e-mail et le mot de passe non validés.

Veillez également à utiliser une URL HTTPS en production pour éviter que votre lien ne soit potentiellement intercepté par des serveurs intermédiaires.

Firebase Authentication utilise Firebase Dynamic Links pour envoyer le lien par e-mail à un appareil mobile. Pour terminer la connexion via l'application mobile, l'application doit être configurée de manière à détecter le lien entrant vers l'application, analyser le lien profond sous-jacent, puis finaliser la connexion.

  1. Consultez ce guide pour configurer votre application pour recevoir des liens dynamiques sur Flutter.

  2. Dans votre gestionnaire de liens, vérifiez si le lien est destiné à l'authentification des liens de messagerie et, le cas échéant, terminez la procédure de connexion.

    // Confirm the link is a sign-in with email link.
    if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) {
      try {
        // The client SDK will parse the code from the link for you.
        final userCredential = await FirebaseAuth.instance
            .signInWithEmailLink(email: emailAuth, emailLink: emailLink);
    
        // You can access the new user via userCredential.user.
        final emailAddress = userCredential.user?.email;
    
        print('Successfully signed in with email link!');
      } catch (error) {
        print('Error signing in with email link.');
      }
    }
    

Vous pouvez également associer cette méthode d'authentification à un utilisateur existant. Par exemple, un utilisateur qui s'est précédemment authentifié auprès d'un autre fournisseur (par exemple, avec un numéro de téléphone) peut ajouter cette méthode de connexion à son compte existant.

La différence se trouverait dans la seconde moitié de l'opération:

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.linkWithCredential(authCredential);
} catch (error) {
    print("Error linking emailLink credential.");
}

Vous pouvez également l'utiliser pour réauthentifier un utilisateur de lien par e-mail avant d'exécuter une opération sensible.

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.reauthenticateWithCredential(authCredential);
} catch (error) {
    print("Error reauthenticating credential.");
}

Toutefois, comme le flux peut se terminer sur un autre appareil où l'utilisateur d'origine n'était pas connecté, il est possible qu'il ne soit pas terminé. Dans ce cas, un message d'erreur peut s'afficher pour forcer l'utilisateur à ouvrir le lien sur le même appareil. Un certain état peut être transmis dans le lien pour fournir des informations sur le type d'opération et l'UID de l'utilisateur.

Si vous avez créé votre projet le 15 septembre 2023 ou après, la protection contre l'énumération des adresses e-mail est activée par défaut. Cette fonctionnalité améliore la sécurité des comptes utilisateur de votre projet, mais elle désactive la méthode fetchSignInMethodsForEmail(), que nous recommandions auparavant pour implémenter des flux d'abord par identifiant.

Bien que vous puissiez désactiver la protection contre l'énumération d'adresses e-mail pour votre projet, nous vous déconseillons de le faire.

Pour en savoir plus, consultez la documentation sur la protection contre l'énumération d'adresses e-mail.

Étapes suivantes

Une fois qu'un utilisateur a créé un compte, celui-ci est stocké dans votre projet Firebase. Il peut être utilisé pour identifier un utilisateur dans toutes les applications de votre projet, quelle que soit la méthode de connexion utilisée.

Dans vos applications, vous pouvez obtenir les informations de profil de base de l'utilisateur à partir de l'objet User. Consultez Gérer les utilisateurs.

Dans Firebase Realtime Database et les règles de sécurité Cloud Storage, vous pouvez obtenir l'ID utilisateur unique de l'utilisateur connecté à partir de la variable auth et l'utiliser pour contrôler les données auxquelles un utilisateur peut accéder.

Vous pouvez autoriser les utilisateurs à se connecter à votre application à l'aide de plusieurs fournisseurs d'authentification en associant les identifiants du fournisseur d'authentification à un compte utilisateur existant.

Pour déconnecter un utilisateur, appelez signOut() :

await FirebaseAuth.instance.signOut();