Save the date - Google I/O returns May 18-20. Register to get the most out of the digital experience: Build your schedule, reserve space, participate in Q&As, earn Google Developer profile badges, and more. Register now
Cette page a été traduite par l'API Cloud Translation.
Switch to English

S'authentifier avec Firebase à l'aide de Email Link dans JavaScript

Vous pouvez utiliser l'authentification Firebase pour connecter un utilisateur en lui envoyant un e-mail contenant un lien sur lequel il peut cliquer pour se connecter. Dans le processus, l'adresse e-mail de l'utilisateur est également vérifiée.

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

  • Inscription et connexion à faible friction.
  • Diminution du risque de réutilisation des mots de passe entre les applications, ce qui peut compromettre la sécurité des mots de passe même bien sélectionnés.
  • La possibilité d'authentifier un utilisateur tout en vérifiant que l'utilisateur 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. Aucune propriété d'un numéro de téléphone ou d'un compte de réseau social n'est requise.
  • Un utilisateur peut se connecter en toute sécurité sans avoir besoin de fournir (ou de se souvenir) d'un mot de passe, ce qui peut être fastidieux sur un appareil mobile.
  • Un utilisateur existant qui s'est précédemment connecté avec un identifiant d'e-mail (mot de passe ou fédéré) peut être mis à niveau pour se connecter uniquement avec l'e-mail. Par exemple, un utilisateur qui a oublié son mot de passe peut toujours se connecter sans avoir à réinitialiser son mot de passe.

Avant que tu commences

Si vous ne l'avez pas déjà fait, copiez l'extrait d'initialisation de la console Firebase dans votre projet comme décrit dans Ajouter Firebase à votre projet JavaScript .

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

  1. Dans la console Firebase , ouvrez la section Auth .
  2. Dans l'onglet Méthode de connexion, activez le fournisseur Email / Mot de passe . Notez que la connexion par e-mail / mot de passe doit être activée pour utiliser la connexion par lien de messagerie.
  3. Dans la même section, activez la méthode de connexion par lien 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 à fournir son adresse e-mail, puis appelez sendSignInLinkToEmail pour demander à Firebase d'envoyer le lien d'authentification à l'e-mail de l'utilisateur.

  1. Construisez l'objet ActionCodeSettings , qui fournit à Firebase des instructions sur la façon de créer le lien de l'e-mail. Définissez les champs suivants:

    • url : Le lien profond à intégrer et tout état supplémentaire à transmettre. Le domaine du lien doit être ajouté dans la liste des domaines autorisés de la console Firebase, que vous pouvez trouver en accédant à l'onglet Méthode de connexion (Authentification -> Méthode de connexion).
    • android et ios : les applications à utiliser lorsque le lien de connexion est ouvert sur un appareil Android ou iOS. En savoir plus sur la configuration de 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 d'e-mail hors bande (réinitialisation du mot de passe et vérifications d'e-mail). En effet, à la fin du flux, l'utilisateur doit être connecté et son état d'authentification persiste 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é.

      Web v8

      var actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

      Web v9

      const actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

    Pour en savoir plus sur ActionCodeSettings, reportez-vous à la section État de transmission dans les actions par e-mail .

  2. Demandez à l'utilisateur son e-mail.

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

    Web v8

    firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        var errorCode = error.code;
        var errorMessage = error.message;
        // ...
      });

    Web v9

    import { getAuth, sendSignInLinkToEmail } from "firebase/auth";
    
    const auth = getAuth();
    sendSignInLinkToEmail(auth, email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        // ...
      });

Problèmes de sécurité

Pour éviter qu'un lien de connexion ne soit utilisé pour se connecter en tant qu'utilisateur involontaire ou sur un appareil non souhaité, Firebase Auth exige que l'adresse e-mail de l'utilisateur soit fournie lors de la procédure de connexion. Pour que la connexion réussisse, cette adresse e-mail doit correspondre à l'adresse à laquelle le lien de connexion a été envoyé à l'origine.

Vous pouvez rationaliser ce flux pour les utilisateurs qui ouvrent le lien de connexion sur le même appareil qu'ils demandent le lien, en stockant leur adresse e-mail localement - par exemple à l'aide de localStorage ou des cookies - lorsque vous envoyez l'e-mail de connexion. Ensuite, utilisez cette adresse pour terminer le flux. Ne transmettez pas l'e-mail de l'utilisateur dans les paramètres de l'URL de redirection et réutilisez-le car cela peut activer les injections de session.

Une fois la connexion terminée, tout mécanisme de connexion non vérifié antérieur sera supprimé de l'utilisateur et toutes les sessions existantes seront invalidées. Par exemple, si quelqu'un a précédemment créé un compte non vérifié avec le même e-mail et le même 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 vérifié de se reconnecter avec l'e-mail et le mot de passe non vérifié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.

Terminer la connexion dans une page Web

Le format du lien profond du lien e-mail est le même que le format utilisé pour les actions d'e-mail hors bande (vérification d'e-mail, réinitialisation du mot de passe et révocation de changement d'e-mail). Firebase Auth simplifie cette vérification en fournissant l'API isSignInWithEmailLink pour vérifier si un lien est une connexion avec un lien de messagerie.

Pour terminer la connexion sur la page de destination, appelez signInWithEmailLink avec l'adresse e-mail de l'utilisateur et le lien e-mail contenant le code à usage unique.

Web v8

// Confirm the link is a sign-in with email link.
if (firebase.auth().isSignInWithEmailLink(window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  var email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  firebase.auth().signInWithEmailLink(email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

Web v9

import { getAuth, isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth";

// Confirm the link is a sign-in with email link.
const auth = getAuth();
if (isSignInWithEmailLink(auth, window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  let email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  signInWithEmailLink(auth, email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

Terminer la connexion dans une application mobile

L'authentification Firebase utilise Firebase Dynamic Links pour envoyer le lien e-mail à un appareil mobile. Pour terminer 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 terminer la connexion comme cela se fait via le flux Web.

Pour en savoir plus sur la gestion de la connexion avec un lien de messagerie dans une application Android, reportez-vous au guide Android .

Pour en savoir plus sur la gestion de la connexion avec un lien de messagerie dans une application iOS, reportez-vous au guide iOS .

Vous pouvez également lier cette méthode d'authentification à un utilisateur existant. Par exemple, un utilisateur précédemment 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 serait dans la seconde moitié de l'opération:

Web v8

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
firebase.auth().currentUser.linkWithCredential(credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

Web v9

import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
const auth = getAuth();
linkWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

Cela peut également être utilisé pour ré-authentifier un utilisateur de lien de messagerie avant d'exécuter une opération sensible.

Web v8

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
firebase.auth().currentUser.reauthenticateWithCredential(credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

Web v9

import { getAuth, reauthenticateWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
const auth = getAuth();
reauthenticateWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

Cependant, comme le flux peut se retrouver sur un appareil différent sur lequel l'utilisateur d'origine n'était pas connecté, ce flux peut ne pas être terminé. Dans ce cas, une erreur peut être montrée à l'utilisateur pour le forcer à 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 utilisateur.

Si vous prenez en charge à la fois la connexion par mot de passe et par lien avec e-mail, pour différencier la méthode de connexion pour un utilisateur de mot de passe / lien, utilisez fetchSignInMethodsForEmail . Ceci est utile pour les flux identifiant d'abord où l'utilisateur est d'abord invité à fournir son e-mail, puis présenté avec la méthode de connexion:

Web v8

// After asking the user for their email.
var email = window.prompt('Please provide your email');
firebase.auth().fetchSignInMethodsForEmail(email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

Web v9

import { getAuth, fetchSignInMethodsForEmail, EmailAuthProvider} from "firebase/auth";

// After asking the user for their email.
const email = window.prompt('Please provide your email');

const auth = getAuth();
fetchSignInMethodsForEmail(auth, email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

Comme décrit ci-dessus, l'e-mail / mot de passe et l'e-mail / lien sont considérés comme le même firebase.auth.EmailAuthProvider (même PROVIDER_ID ) avec différentes méthodes de connexion.

Prochaines étapes

Lorsqu'un utilisateur se connecte pour la première fois, un nouveau compte utilisateur est créé et lié aux informations d'identification (c'est-à-dire le nom d'utilisateur et le mot de passe, le numéro de téléphone ou les informations du fournisseur d'authentification) avec lesquels l'utilisateur s'est connecté. Ce nouveau compte est stocké dans le cadre de votre projet Firebase et peut être utilisé pour identifier un utilisateur dans chaque application de votre projet, quelle que soit la manière dont l'utilisateur se connecte.

  • Dans vos applications, la méthode recommandée pour connaître l'état d'authentification de votre utilisateur consiste à définir un observateur sur l'objet Auth . Vous pouvez ensuite obtenir les informations de profil de base de l' User partir de l'objet User . Voir 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 liant les informations d'identification du fournisseur d'authentification à un compte d'utilisateur existant.

Pour déconnecter un utilisateur, appelez l' signOut

Web v8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web v9

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});