Aggiungi l'autenticazione a più fattori TOTP alla tua app Web

Se hai eseguito l'upgrade all'autenticazione Firebase con Identity Platform, puoi aggiungere l'autenticazione a più fattori (MFA) con password monouso basata sul tempo (TOTP) alla tua app.

L'autenticazione Firebase con Identity Platform ti consente di utilizzare un TOTP come fattore aggiuntivo per l'MFA. Quando abiliti questa funzionalità, gli utenti che tentano di accedere alla tua app vedono una richiesta di TOTP. Per generarlo, devono utilizzare un'app di autenticazione in grado di generare codici TOTP validi, come Google Authenticator .

Prima di iniziare

  1. Abilita almeno un provider che supporti l'MFA. Tieni presente che tutti i fornitori, tranne i seguenti, supportano l'MFA:

    • Aut. telefono
    • Aut. anonima
    • Token di autenticazione personalizzati
    • Centro giochi Apple
  2. Assicurati che la tua app verifichi gli indirizzi email degli utenti. L'AMF richiede la verifica dell'e-mail. Ciò impedisce agli autori malintenzionati di registrarsi a un servizio con un indirizzo e-mail di cui non sono proprietari e quindi di bloccare l'effettivo proprietario dell'indirizzo e-mail aggiungendo un secondo fattore.

  3. Se non l'hai già fatto, installa Firebase JavaScript SDK .

    TOTP MFA è supportato solo sull'SDK Web modulare, versioni v9.19.1 e successive.

Abilita MFA TOTP

Per abilitare TOTP come secondo fattore, utilizza Admin SDK o chiama l'endpoint REST di configurazione del progetto.

Per utilizzare l'SDK Admin, procedi come segue:

  1. Se non lo hai già fatto, installa l' SDK Firebase Admin Node.js.

    TOTP MFA è supportato solo sulle versioni SDK Firebase Admin Node.js 11.6.0 e successive.

  2. Esegui quanto segue:

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

    Sostituisci quanto segue:

    • NUM_ADJ_INTERVALS : il numero di intervalli di finestre temporali adiacenti da cui accettare TOTP, da zero a dieci. Il valore predefinito è cinque.

      I TOTP funzionano garantendo che quando due parti (il prover e il validatore) generano OTP nello stesso intervallo di tempo (in genere lungo 30 secondi), generino la stessa password. Tuttavia, per tenere conto dello scostamento dell'orario tra le parti e dei tempi di risposta umana, è possibile configurare il servizio TOTP in modo che accetti anche TOTP da finestre adiacenti.

Per abilitare TOTP MFA utilizzando l'API REST, esegui quanto segue:

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"
            }
          }]
       }
    }'

Sostituisci quanto segue:

  • PROJECT_ID : l'ID del progetto.
  • NUM_ADJ_INTERVALS : il numero di intervalli della finestra temporale, da zero a dieci. Il valore predefinito è cinque.

    I TOTP funzionano garantendo che quando due parti (il prover e il validatore) generano OTP nello stesso intervallo di tempo (in genere lungo 30 secondi), generino la stessa password. Tuttavia, per tenere conto dello scostamento dell'orario tra le parti e dei tempi di risposta umana, è possibile configurare il servizio TOTP in modo che accetti anche TOTP da finestre adiacenti.

Scegli un modello di iscrizione

Puoi scegliere se la tua app richiede l'autenticazione a più fattori e come e quando registrare i tuoi utenti. Alcuni modelli comuni includono quanto segue:

  • Registra il secondo fattore dell'utente come parte della registrazione. Utilizza questo metodo se la tua app richiede l'autenticazione a più fattori per tutti gli utenti.

  • Offri un'opzione ignorabile per iscrivere un secondo fattore durante la registrazione. Se vuoi incoraggiare ma non richiedere l'autenticazione a più fattori nella tua app, potresti utilizzare questo approccio.

  • Fornire la possibilità di aggiungere un secondo fattore dall'account dell'utente o dalla pagina di gestione del profilo, anziché dalla schermata di registrazione. Ciò riduce al minimo gli attriti durante il processo di registrazione, pur rendendo disponibile l’autenticazione a più fattori per gli utenti sensibili alla sicurezza.

  • Richiedere l'aggiunta incrementale di un secondo fattore quando l'utente desidera accedere a funzionalità con requisiti di sicurezza maggiori.

Iscrivi gli utenti a TOTP MFA

Dopo aver abilitato TOTP MFA come secondo fattore per la tua app, implementa la logica lato client per iscrivere gli utenti a TOTP MFA:

  1. Importa le classi e le funzioni MFA richieste:

    import {
      multiFactor,
      TotpMultiFactorGenerator,
      TotpSecret,
      getAuth,
    } from "firebase/auth";
    
  2. Riautenticare l'utente.

  3. Genera un segreto TOTP per l'utente autenticato:

    // Generate a TOTP secret.
    const multiFactorSession = await multiFactor(currentUser).getSession();
    const totpSecret = await TotpMultiFactorGenerator.generateSecret(
      multiFactorSession
    );
    
  4. Mostra il segreto all'utente e chiedigli di inserirlo nell'app di autenticazione.

    Con molte app di autenticazione, gli utenti possono aggiungere rapidamente nuovi segreti TOTP eseguendo la scansione di un codice QR che rappresenta un URI di chiave compatibile con Google Authenticator . Per generare un codice QR a questo scopo, genera l'URI con generateQrCodeUrl() e quindi codificalo utilizzando la libreria di codici QR di tua scelta. Per esempio:

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

    Indipendentemente dal fatto che visualizzi o meno un codice QR, mostra sempre la chiave segreta per supportare le app di autenticazione che non possono leggere i codici QR:

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

    Dopo che l'utente ha aggiunto il proprio segreto all'app di autenticazione, inizierà a generare TOTP.

  5. Chiedi all'utente di digitare il TOTP visualizzato nell'app di autenticazione e di utilizzarlo per finalizzare la registrazione 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);
    

Accedi agli utenti con un secondo fattore

Per accedere agli utenti con TOTP MFA, utilizzare il seguente codice:

  1. Importa le classi e le funzioni MFA richieste:

    import {
        getAuth,
        getMultiFactorResolver,
        TotpMultiFactorGenerator,
    } from "firebase/auth";
    
  2. Chiama uno dei metodi signInWith come faresti se non utilizzassi MFA. (Ad esempio, signInWithEmailAndPassword() .) Se il metodo genera un errore auth/multi-factor-auth-required , avvia il flusso MFA dell'app.

    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. Il flusso MFA della tua app dovrebbe innanzitutto richiedere all'utente di scegliere il secondo fattore che desidera utilizzare. Puoi ottenere un elenco dei secondi fattori supportati esaminando la proprietà hints di un'istanza MultiFactorResolver :

    const mfaResolver = getMultiFactorResolver(getAuth(), error);
    const enrolledFactors = mfaResolver.hints.map(info => info.displayName);
    
  4. Se l'utente sceglie di utilizzare TOTP, chiedigli di digitare il TOTP visualizzato sull'app di autenticazione e di utilizzarlo per accedere:

    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;
    }
    

Annulla l'iscrizione a TOTP MFA

Questa sezione descrive come gestire l'annullamento dell'iscrizione a TOTP MFA da parte di un utente.

Se un utente si è registrato per più opzioni MFA e annulla la registrazione dall'opzione abilitata più di recente, riceve un messaggio auth/user-token-expired e viene disconnesso. L'utente deve accedere nuovamente e verificare le proprie credenziali esistenti, ad esempio un indirizzo e-mail e una password.

Per annullare la registrazione dell'utente, gestire l'errore e attivare la riautenticazione, utilizzare il seguente codice:

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
        );
    }
}

Qual è il prossimo