Authentifiez-vous avec Firebase à l'aide d'Email Link dans Android

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:

  • Une inscription et une connexion fluides
  • Risque réduit de réutilisation de mots de passe dans les applications, ce qui peut compromettre la sécurité même des mots de passe 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

Configurer votre projet Android

  1. Si ce n'est pas encore fait, ajoutez Firebase à votre projet Android.

  2. Dans le fichier Gradle de votre module (au niveau de l'application) (généralement <project>/<app-module>/build.gradle.kts ou <project>/<app-module>/build.gradle), ajoutez la dépendance pour la bibliothèque Firebase Authentication pour Android. Nous vous recommandons d'utiliser Firebase Android BoM pour contrôler le contrôle des versions de la bibliothèque.

    De plus, lors de la configuration de Firebase Authentication, vous devez ajouter le SDK des services Google Play à votre application.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0")
    }

    En utilisant Firebase Android BoM, votre application utilisera toujours des versions compatibles des bibliothèques Firebase Android.

    (Alternative) Ajoutez des dépendances de bibliothèque Firebase sans utiliser BoM.

    Si vous choisissez de ne pas utiliser Firebase BoM, vous devez spécifier chaque version de la bibliothèque Firebase dans sa ligne de dépendance.

    Notez que si vous utilisez plusieurs bibliothèques Firebase dans votre application, nous vous recommandons vivement d'utiliser BoM pour gérer les versions de la bibliothèque, ce qui garantit que toutes les versions sont compatibles.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.1.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0")
    }
    Vous recherchez un module de bibliothèque spécifique à Kotlin ? À partir d'octobre 2023 (Firebase BoM 32.5.0), les développeurs Kotlin et Java peuvent dépendre du module de bibliothèque principal (pour en savoir plus, consultez les questions fréquentes sur cette initiative).

Pour permettre aux utilisateurs de se connecter à l'aide d'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 à l'utilisateur une interface qui l'invite à 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 création du lien par e-mail. Attribuez aux champs suivants les valeurs correspondantes :

    • url: lien profond à intégrer et état supplémentaire à transmettre. Le domaine du lien doit être ajouté à 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 Apple. Découvrez comment configurer Firebase Dynamic Links pour ouvrir des liens d'action par e-mail via des applications mobiles.
    • handleCodeInApp: défini sur "true". L'opération de connexion doit toujours être effectuée dans l'application, contrairement aux 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 persister dans l'application.
    • dynamicLinkDomain: lorsque plusieurs domaines de liens dynamiques personnalisés sont définis pour un projet, spécifiez 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é.

    Kotlin

    val actionCodeSettings = 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
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
            "com.example.android",
            true, // installIfNotAvailable
            "12", // minimumVersion
        )
    }

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    Pour en savoir plus sur ActionCodeSettings, consultez la section Transmettre l'état dans les actions par e-mail.

  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.

    Kotlin

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Email sent.")
            }
        }

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

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 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.

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

Finaliser la connexion dans une application Android

Firebase Authentication utilise Firebase Dynamic Links pour envoyer le lien par e-mail à un appareil mobile. Pour que la connexion soit effectuée 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 effectuer la connexion.

Firebase Auth utilise Firebase Dynamic Links lors de l'envoi d'un lien destiné à être ouvert dans une application mobile. Pour utiliser cette fonctionnalité, les liens dynamiques doivent être configurés dans la console Firebase.

  1. Activez Firebase Dynamic Links:

    1. Dans la console Firebase, ouvrez la section Dynamic Links.
    2. Si vous n'avez pas encore accepté les conditions d'utilisation de Dynamic Links et créé de domaine Dynamic Links, faites-le maintenant.

      Si vous avez déjà créé un domaine Dynamic Links, notez-le. Un domaine Dynamic Links se présente généralement comme suit:

      example.page.link

      Vous aurez besoin de cette valeur lorsque vous configurerez votre application Apple ou Android pour intercepter le lien entrant.

  2. Configurer des applications Android:

    1. Pour gérer ces liens à partir de votre application Android, le nom du package Android doit être spécifié dans les paramètres du projet de la Firebase Console. De plus, les valeurs SHA-1 et SHA-256 du certificat de l'application doivent être fournies.
    2. Maintenant que vous avez ajouté un domaine de lien dynamique et que vous vous êtes assuré que votre application Android est correctement configurée, le lien dynamique redirige vers votre application, à partir de l'activité du lanceur d'applications.
    3. Si vous souhaitez que le lien dynamique redirige vers une activité spécifique, vous devez configurer un filtre d'intent dans votre fichier AndroidManifest.xml. Pour ce faire, spécifiez votre domaine de lien dynamique ou le gestionnaire d'action par e-mail dans le filtre d'intent. Par défaut, le gestionnaire d'action par e-mail est hébergé sur un domaine semblable à celui-ci:
      PROJECT_ID.firebaseapp.com/
    4. Mises en garde :
      1. Ne spécifiez pas l'URL que vous définissez sur actionCodeSettings dans votre filtre d'intent.
      2. Lorsque vous avez créé votre domaine de liens dynamiques, vous avez peut-être également créé un lien d'URL courte. Cette URL courte ne sera pas transmise. Ne configurez pas votre filtre d'intent pour la capturer avec un attribut android:pathPrefix. Cela signifie que vous ne pourrez pas capturer différents liens dynamiques dans différentes parties de votre application. Toutefois, vous pouvez vérifier le paramètre de requête mode dans le lien pour voir quelle opération est tentée, ou utiliser des méthodes de SDK telles que isSignInWithEmailLink pour voir si un lien que votre application a reçu fait ce que vous voulez.
    5. Pour en savoir plus sur la réception de liens dynamiques, consultez les instructions de réception des liens dynamiques Android.

Une fois que vous avez reçu le lien comme décrit ci-dessus, vérifiez qu'il est destiné à l'authentification du lien d'e-mail, puis finalisez la connexion.

Kotlin

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully signed in with email link!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error signing in with email link", task.exception)
            }
        }
}

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

Pour en savoir plus sur la gestion de la connexion avec un lien d'e-mail dans une application Apple, consultez le guide des plates-formes Apple.

Pour savoir comment gérer la connexion avec un lien e-mail dans une application Web, consultez le guide Web.

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 situe dans la seconde moitié de l'opération:

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d(TAG, "Successfully linked emailLink credential!")
            val result = task.result
            // You can access the new user via result.getUser()
            // Additional user info profile *not* available via:
            // result.getAdditionalUserInfo().getProfile() == null
            // You can check if the user is new or existing:
            // result.getAdditionalUserInfo().isNewUser()
        } else {
            Log.e(TAG, "Error linking emailLink credential", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

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

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            // User is now successfully reauthenticated
        } else {
            Log.e(TAG, "Error reauthenticating", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

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

Lorsqu'un utilisateur se connecte pour la première fois, un compte utilisateur est créé et associé aux identifiants (nom d'utilisateur et mot de passe, numéro de téléphone ou informations du fournisseur d'authentification) avec lesquels l'utilisateur s'est connecté. Ce nouveau compte 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 manière dont il se connecte.

  • Dans vos applications, vous pouvez obtenir les informations de profil de base de l'utilisateur à partir de l'objet FirebaseUser. 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 les identifiants du fournisseur d'authentification à un compte utilisateur existant.

Pour déconnecter un utilisateur, appelez signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();