Ajoutez l'authentification multifacteur TOTP à votre application Web

Si vous avez effectué une mise à niveau vers l'authentification Firebase avec Identity Platform, vous pouvez ajouter une authentification multifacteur (MFA) par mot de passe à usage unique (TOTP) basée sur le temps à votre application.

L'authentification Firebase avec Identity Platform vous permet d'utiliser un TOTP comme facteur supplémentaire pour l'authentification multifacteur. Lorsque vous activez cette fonctionnalité, les utilisateurs qui tentent de se connecter à votre application voient une demande de TOTP. Pour le générer, ils doivent utiliser une application d'authentification capable de générer des codes TOTP valides, comme Google Authenticator .

Avant que tu commences

  1. Activez au moins un fournisseur prenant en charge MFA. Notez que tous les fournisseurs, à l'exception des suivants, prennent en charge MFA :

    • Authentification téléphonique
    • Authentification anonyme
    • Jetons d'authentification personnalisés
    • Centre de jeux Apple
  2. Assurez-vous que votre application vérifie les adresses e-mail des utilisateurs. MFA nécessite une vérification par e-mail. Cela empêche les acteurs malveillants de s'inscrire à un service avec une adresse e-mail qui ne leur appartient pas, puis de verrouiller le véritable propriétaire de l'adresse e-mail en ajoutant un deuxième facteur.

  3. Si vous ne l'avez pas déjà fait, installez le SDK JavaScript Firebase .

    TOTP MFA est uniquement pris en charge sur le SDK Web modulaire, versions v9.19.1 et supérieures.

Activer l'authentification multifacteur TOTP

Pour activer TOTP comme deuxième facteur, utilisez le SDK Admin ou appelez le point de terminaison REST de configuration du projet.

Pour utiliser le SDK Admin, procédez comme suit :

  1. Si vous ne l'avez pas déjà fait, installez le SDK Firebase Admin Node.js .

    TOTP MFA est uniquement pris en charge sur les versions 11.6.0 et supérieures du SDK Firebase Admin Node.js.

  2. Exécutez ce qui suit :

    import { getAuth } from 'firebase-admin/auth';
    
    getAuth().projectConfigManager().updateProjectConfig(
    {
          multiFactorConfig: {
              providerConfigs: [{
                  state: "ENABLED",
                  totpProviderConfig: {
                      adjacentIntervals: {
                          NUM_ADJ_INTERVALS
                      },
                  }
              }]
          }
    })
    

    Remplacez les éléments suivants :

    • NUM_ADJ_INTERVALS : nombre d'intervalles de fenêtre de temps adjacents à partir desquels accepter les TOTP, de zéro à dix. La valeur par défaut est cinq.

      Les TOTP fonctionnent en garantissant que lorsque deux parties (le prouveur et le validateur) génèrent des OTP dans la même fenêtre de temps (généralement 30 secondes), elles génèrent le même mot de passe. Toutefois, pour tenir compte de la dérive d'horloge entre les parties et du temps de réponse humain, vous pouvez configurer le service TOTP pour qu'il accepte également les TOTP des fenêtres adjacentes.

Pour activer TOTP MFA à l'aide de l'API REST, exécutez ce qui suit :

curl -X PATCH "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=mfa" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    -d \
    '{
        "mfa": {
          "providerConfigs": [{
            "state": "ENABLED",
            "totpProviderConfig": {
              "adjacentIntervals": "NUM_ADJ_INTERVALS"
            }
          }]
       }
    }'

Remplacez les éléments suivants :

  • PROJECT_ID : ID du projet.
  • NUM_ADJ_INTERVALS : le nombre d'intervalles de fenêtre temporelle, de zéro à dix. La valeur par défaut est cinq.

    Les TOTP fonctionnent en garantissant que lorsque deux parties (le prouveur et le validateur) génèrent des OTP dans la même fenêtre de temps (généralement 30 secondes), elles génèrent le même mot de passe. Toutefois, pour tenir compte de la dérive d'horloge entre les parties et du temps de réponse humain, vous pouvez configurer le service TOTP pour qu'il accepte également les TOTP des fenêtres adjacentes.

Choisissez un modèle d'inscription

Vous pouvez choisir si votre application nécessite une authentification multifacteur, ainsi que comment et quand inscrire vos utilisateurs. Certains modèles courants sont les suivants :

  • Inscrivez le deuxième facteur de l'utilisateur dans le cadre de l'inscription. Utilisez cette méthode si votre application nécessite une authentification multifacteur pour tous les utilisateurs.

  • Offrez une option désactivable pour inscrire un deuxième facteur lors de l’inscription. Si vous souhaitez encourager mais ne pas exiger l'authentification multifacteur dans votre application, vous pouvez utiliser cette approche.

  • Offrez la possibilité d'ajouter un deuxième facteur à partir de la page de gestion du compte ou du profil de l'utilisateur, au lieu de l'écran d'inscription. Cela minimise les frictions pendant le processus d'enregistrement, tout en rendant l'authentification multifacteur disponible pour les utilisateurs sensibles à la sécurité.

  • Exiger l'ajout d'un deuxième facteur de manière incrémentielle lorsque l'utilisateur souhaite accéder à des fonctionnalités présentant des exigences de sécurité accrues.

Inscrire des utilisateurs dans TOTP MFA

Après avoir activé TOTP MFA comme deuxième facteur pour votre application, implémentez une logique côté client pour inscrire les utilisateurs dans TOTP MFA :

  1. Importez les classes et fonctions MFA requises :

    import {
      multiFactor,
      TotpMultiFactorGenerator,
      TotpSecret,
      getAuth,
    } from "firebase/auth";
    
  2. Réauthentifiez l'utilisateur.

  3. Générez un secret TOTP pour l'utilisateur authentifié :

    // Generate a TOTP secret.
    const multiFactorSession = await multiFactor(currentUser).getSession();
    const totpSecret = await TotpMultiFactorGenerator.generateSecret(
      multiFactorSession
    );
    
  4. Affichez le secret à l'utilisateur et invitez-le à le saisir dans son application d'authentification.

    Avec de nombreuses applications d'authentification, les utilisateurs peuvent ajouter rapidement de nouveaux secrets TOTP en scannant un code QR qui représente un URI de clé compatible avec Google Authenticator . Pour générer un code QR à cet effet, générez l'URI avec generateQrCodeUrl() puis encodez-le à l'aide de la bibliothèque de codes QR de votre choix. Par exemple:

    const totpUri = totpSecret.generateQrCodeUrl(
        currentUser.email,
        "Your App's Name"
    );
    await QRExampleLib.toCanvas(totpUri, qrElement);
    

    Que vous affichiez ou non un code QR, affichez toujours la clé secrète pour prendre en charge les applications d'authentification qui ne peuvent pas lire les codes QR :

    // Also display this key:
    const secret = totpSecret.secretKey;
    

    Une fois que l'utilisateur a ajouté son secret à son application d'authentification, celle-ci commencera à générer des TOTP.

  5. Invitez l'utilisateur à saisir le TOTP affiché sur son application d'authentification et à l'utiliser pour finaliser l'inscription MFA :

    // Ask the user for a verification code from the authenticator app.
    const verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment(
      totpSecret,
      verificationCode
    );
    await multiFactor(currentUser).enroll(multiFactorAssertion, mfaDisplayName);
    

Connectez les utilisateurs avec un deuxième facteur

Pour connecter les utilisateurs avec TOTP MFA, utilisez le code suivant :

  1. Importez les classes et fonctions MFA requises :

    import {
        getAuth,
        getMultiFactorResolver,
        TotpMultiFactorGenerator,
    } from "firebase/auth";
    
  2. Appelez l’une des méthodes signInWith - comme vous le feriez si vous n’utilisiez pas MFA. (Par exemple, signInWithEmailAndPassword() .) Si la méthode renvoie une erreur auth/multi-factor-auth-required , démarrez le flux MFA de votre application.

    try {
        const userCredential = await signInWithEmailAndPassword(
            getAuth(),
            email,
            password
        );
        // If the user is not enrolled with a second factor and provided valid
        // credentials, sign-in succeeds.
    
        // (If your app requires MFA, this could be considered an error
        // condition, which you would resolve by forcing the user to enroll a
        // second factor.)
    
        // ...
    } catch (error) {
        switch (error.code) {
            case "auth/multi-factor-auth-required":
                // Initiate your second factor sign-in flow. (See next step.)
                // ...
                break;
            case ...:  // Handle other errors, such as wrong passwords.
                break;
        }
    }
    
  3. Le flux MFA de votre application doit d’abord inviter l’utilisateur à choisir le deuxième facteur qu’il souhaite utiliser. Vous pouvez obtenir une liste des seconds facteurs pris en charge en examinant la propriété hints d'une instance MultiFactorResolver :

    const mfaResolver = getMultiFactorResolver(getAuth(), error);
    const enrolledFactors = mfaResolver.hints.map(info => info.displayName);
    
  4. Si l'utilisateur choisit d'utiliser TOTP, invitez-le à saisir le TOTP affiché sur son application d'authentification et à l'utiliser pour se connecter :

    switch (mfaResolver.hints[selectedIndex].factorId) {
        case TotpMultiFactorGenerator.FACTOR_ID:
            const otpFromAuthenticator = // OTP typed by the user.
            const multiFactorAssertion =
                TotpMultiFactorGenerator.assertionForSignIn(
                    mfaResolver.hints[selectedIndex].uid,
                    otpFromAuthenticator
                );
            try {
                const userCredential = await mfaResolver.resolveSignIn(
                    multiFactorAssertion
                );
                // Successfully signed in!
            } catch (error) {
                // Invalid or expired OTP.
            }
            break;
        case PhoneMultiFactorGenerator.FACTOR_ID:
            // Handle SMS second factor.
            break;
        default:
            // Unsupported second factor?
            break;
    }
    

Se désinscrire de TOTP MFA

Cette section décrit comment gérer la désinscription d'un utilisateur de TOTP MFA.

Si un utilisateur s'est inscrit à plusieurs options MFA et s'il se désinscrit de l'option la plus récemment activée, il reçoit un message auth/user-token-expired et est déconnecté. L'utilisateur doit se reconnecter et vérifier ses informations d'identification existantes, par exemple une adresse e-mail et un mot de passe.

Pour désinscrire l'utilisateur, gérer l'erreur et déclencher la réauthentification, utilisez le code suivant :

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

try {
    // Unenroll from TOTP MFA.
    await multiFactor(currentUser).unenroll(mfaEnrollmentId);
} catch  (error) {
    if (error.code === 'auth/user-token-expired') {
        // If the user was signed out, re-authenticate them.

        // For example, if they signed in with a password, prompt them to
        // provide it again, then call `reauthenticateWithCredential()` as shown
        // below.

        const credential = EmailAuthProvider.credential(email, password);
        await reauthenticateWithCredential(
            currentUser,
            credential
        );
    }
}

Et après