S'authentifier avec Firebase à l'aide de liens par 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 de ce processus, l'adresse e-mail de l'utilisateur est également validée.

La connexion par e-mail présente de nombreux avantages :

  • Inscription et connexion simples
  • Réduction du risque de réutilisation de mots de passe dans plusieurs applications, ce qui peut compromettre la sécurité même des mots de passe bien choisis
  • Possibilité d'authentifier un utilisateur tout en vérifiant qu'il est le propriétaire légitime d'une adresse e-mail
  • Un utilisateur n'a besoin que d'un compte de messagerie accessible pour se connecter. Il n'est pas nécessaire de posséder un numéro de téléphone ni 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 fastidieux sur un appareil mobile.
  • Un utilisateur existant qui s'est déjà connecté avec un identifiant de messagerie (mot de passe ou fédéré) peut être mis à niveau pour se connecter uniquement avec son adresse e-mail. 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 envoyé par e-mail pour votre projet Firebase.

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

    1. Dans la console Firebase, accédez à Sécurité > Authentification.

    2. Dans l'onglet Méthode de connexion, activez le fournisseur de connexion Adresse e-mail/Mot de passe. Notez que la connexion par adresse e-mail/mot de passe doit être activée pour utiliser la connexion par lien envoyé par 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 invitant l'utilisateur à indiquer 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 façon de créer le lien envoyé par e-mail. Renseignez les champs ci-dessous comme suit :

    • url : lien profond à intégrer et tout état supplémentaire à transmettre. Si ce n'est pas déjà fait, ajoutez le domaine du lien à la liste des domaines autorisés :

      1. Dans la console Firebase, accédez à l'onglet Authentification > Paramètres.

      2. Dans la section Domaines autorisés, cliquez sur Ajouter un domaine, puis ajoutez le domaine du lien.

      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.

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

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

    • linkDomain: domaine Firebase Hosting personnalisé facultatif à utiliser lorsque le lien doit être ouvert à l'aide d'une application mobile spécifiée. Le domaine doit être configuré dans Firebase Hosting et appartenir au projet. Il ne peut pas s'agir d'un domaine Hosting par défaut (web.app ou firebaseapp.com). Il remplace le paramètre obsolète dynamicLinkDomain.

    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 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 effectue 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 prévu ou sur un appareil non prévu, Firebase Auth exige que l'adresse e-mail de l'utilisateur soit fournie lors de la finalisation du flux de connexion. Pour que la connexion réussisse, 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 que celui sur lequel ils ont demandé le lien, 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 flux. Ne transmettez pas l'adresse e-mail de l'utilisateur dans les paramètres de l'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 non validé précédent sera supprimé de l'utilisateur et toutes les sessions existantes seront invalidées. Par exemple, si une personne a déjà créé un compte non validé avec la même adresse e-mail et le même mot de passe, le mot de passe de l'utilisateur sera supprimé pour empêcher l'usurpateur qui a revendiqué la propriété et créé ce compte non validé de se connecter à nouveau avec l'adresse e-mail et le mot de passe non validés.

Assurez-vous également d'utiliser une URL HTTPS en production pour éviter que votre lien ne soit potentiellement intercepté par des serveurs intermédiaires.

Finaliser la connexion

Firebase Dynamic Links est obsolète. Firebase Hosting est désormais utilisé pour envoyer un lien de connexion. Suivez les guides de configuration spécifiques à la plate-forme :

Pour finaliser la connexion via une application mobile, l'application doit être configurée pour détecter le lien d'application entrant, analyser le lien profond sous-jacent, puis finaliser la connexion.

  1. Dans votre gestionnaire de liens, vérifiez si le lien est destiné à l'authentification par lien envoyé par e-mail et, le cas échéant, finalisez le processus 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 déjà authentifié auprès d'un autre fournisseur, tel qu'un numéro de téléphone, peut ajouter cette méthode de connexion à son compte existant.

La différence se situe 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.");
}

Cette méthode peut également être utilisée pour réauthentifier un utilisateur de lien envoyé 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 sur lequel l'utilisateur d'origine n'était pas connecté, il est possible qu'il ne soit pas finalisé. Dans ce cas, un message d'erreur peut s'afficher pour l'utilisateur afin de l'obliger à ouvrir le lien sur le même appareil. Un é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 d'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'identifiants en premier.

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

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

Étapes suivantes

Lorsqu'un utilisateur crée un compte, celui-ci est stocké dans votre projet Firebase et 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 base du profil de l'utilisateur à partir de l'objet User. Consultez Gérer les utilisateurs.

Dans vos règles de sécurité Firebase Realtime Database et 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 des identifiants de fournisseur d'authentification) à un compte utilisateur existant.

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

await FirebaseAuth.instance.signOut();