Dodaj uwierzytelnianie wieloskładnikowe do swojej aplikacji internetowej

Jeśli dokonałeś aktualizacji do uwierzytelniania Firebase z platformą tożsamości, możesz dodać wieloskładnikowe uwierzytelnianie SMS do swojej aplikacji internetowej.

Uwierzytelnianie wieloskładnikowe zwiększa bezpieczeństwo Twojej aplikacji. Chociaż napastnicy często naruszają hasła i konta społecznościowe, przechwycenie wiadomości tekstowej jest trudniejsze.

Zanim zaczniesz

  1. Włącz co najmniej jednego dostawcę obsługującego uwierzytelnianie wieloskładnikowe. Każdy dostawca obsługuje usługę MFA, z wyjątkiem uwierzytelniania telefonicznego, uwierzytelniania anonimowego i Apple Game Center.

  2. Upewnij się, że Twoja aplikacja weryfikuje adresy e-mail użytkowników. MFA wymaga weryfikacji e-mailowej. Zapobiega to rejestrowaniu się złośliwych aktorów w usłudze przy użyciu adresu e-mail, którego nie należą, a następnie blokowaniu prawdziwego właściciela poprzez dodanie drugiego czynnika.

Korzystanie z wielu najemców

Jeśli włączasz uwierzytelnianie wieloskładnikowe do użytku w środowisku wielu dzierżawców , wykonaj następujące kroki (oprócz pozostałych instrukcji zawartych w tym dokumencie):

  1. W konsoli GCP wybierz dzierżawcę, z którym chcesz pracować.

  2. W swoim kodzie ustaw pole tenantId w wystąpieniu Auth na identyfikator dzierżawy. Na przykład:

    Modułowe API sieciowe

    import { getAuth } from "firebase/auth";
    
    const auth = getAuth(app);
    auth.tenantId = "myTenantId1";
    

    Internetowy interfejs API z przestrzenią nazw

    firebase.auth().tenantId = 'myTenantId1';
    

Włączanie uwierzytelniania wieloskładnikowego

  1. Otwórz stronę Uwierzytelnianie > Metoda logowania w konsoli Firebase.

  2. W sekcji Zaawansowane włącz uwierzytelnianie wieloskładnikowe SMS .

    Powinieneś także wpisać numery telefonów, z którymi będziesz testować aplikację. Chociaż jest to opcjonalne, zdecydowanie zaleca się rejestrowanie testowych numerów telefonów, aby uniknąć ograniczania przepustowości podczas programowania.

  3. Jeśli nie autoryzowałeś jeszcze domeny swojej aplikacji, dodaj ją do listy dozwolonych na stronie Uwierzytelnianie > Ustawienia w konsoli Firebase.

Wybór wzoru zapisu

Możesz wybrać, czy Twoja aplikacja wymaga uwierzytelniania wieloskładnikowego oraz jak i kiedy rejestrować użytkowników. Niektóre typowe wzorce obejmują:

  • Zarejestruj drugi czynnik użytkownika w ramach rejestracji. Użyj tej metody, jeśli aplikacja wymaga uwierzytelniania wieloskładnikowego dla wszystkich użytkowników.

  • Zaoferuj możliwość pominięcia opcji zapisania drugiego czynnika podczas rejestracji. Aplikacje, które chcą zachęcać do uwierzytelniania wieloskładnikowego, ale go nie wymagają, mogą preferować to podejście.

  • Zapewnij możliwość dodania drugiego elementu ze strony zarządzania kontem lub profilem użytkownika zamiast ekranu rejestracji. Minimalizuje to problemy podczas procesu rejestracji, jednocześnie udostępniając uwierzytelnianie wieloskładnikowe użytkownikom wrażliwym na bezpieczeństwo.

  • Wymagaj stopniowego dodawania drugiego czynnika, gdy użytkownik chce uzyskać dostęp do funkcji o podwyższonych wymaganiach bezpieczeństwa.

Konfigurowanie weryfikatora reCAPTCHA

Zanim będziesz mógł wysyłać kody SMS, musisz skonfigurować weryfikator reCAPTCHA. Firebase używa reCAPTCHA, aby zapobiegać nadużyciom, upewniając się, że prośby o weryfikację numeru telefonu pochodzą z jednej z domen dozwolonych w Twojej aplikacji.

Nie musisz ręcznie konfigurować klienta reCAPTCHA; Obiekt RecaptchaVerifier pakietu SDK klienta automatycznie tworzy i inicjuje wszelkie niezbędne klucze i wpisy tajne klienta.

Używanie niewidocznego reCAPTCHA

Obiekt RecaptchaVerifier obsługuje niewidoczną reCAPTCHA , która często może zweryfikować użytkownika bez konieczności jakiejkolwiek interakcji. Aby użyć niewidocznej reCAPTCHA, utwórz RecaptchaVerifier z parametrem size ustawionym na invisible i określ identyfikator elementu interfejsu użytkownika, który rozpoczyna rejestrację wieloczynnikową:

Modułowe API sieciowe

import { RecaptchaVerifier } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier("sign-in-button", {
    "size": "invisible",
    "callback": function(response) {
        // reCAPTCHA solved, you can proceed with
        // phoneAuthProvider.verifyPhoneNumber(...).
        onSolvedRecaptcha();
    }
}, auth);

Internetowy interfejs API z przestrzenią nazw

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': function(response) {
  // reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
  onSolvedRecaptcha();
}
});

Korzystanie z widżetu reCAPTCHA

Aby użyć widocznego widżetu reCAPTCHA, utwórz element HTML zawierający widżet, a następnie utwórz obiekt RecaptchaVerifier z identyfikatorem kontenera interfejsu użytkownika. Opcjonalnie możesz także ustawić wywołania zwrotne, które będą wywoływane, gdy reCAPTCHA zostanie rozwiązany lub wygaśnie:

Modułowe API sieciowe

import { RecaptchaVerifier } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha-container",

    // Optional reCAPTCHA parameters.
    {
      "size": "normal",
      "callback": function(response) {
        // reCAPTCHA solved, you can proceed with
        // phoneAuthProvider.verifyPhoneNumber(...).
        onSolvedRecaptcha();
      },
      "expired-callback": function() {
        // Response expired. Ask user to solve reCAPTCHA again.
        // ...
      }
    }, auth
);

Internetowy interfejs API z przestrzenią nazw

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
  'recaptcha-container',
  // Optional reCAPTCHA parameters.
  {
    'size': 'normal',
    'callback': function(response) {
      // reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
      // ...
      onSolvedRecaptcha();
    },
    'expired-callback': function() {
      // Response expired. Ask user to solve reCAPTCHA again.
      // ...
    }
  });

Wstępne renderowanie pliku reCAPTCHA

Opcjonalnie możesz wstępnie wyrenderować reCAPTCHA przed rozpoczęciem rejestracji dwuskładnikowej:

Modułowe API sieciowe

recaptchaVerifier.render()
    .then(function (widgetId) {
        window.recaptchaWidgetId = widgetId;
    });

Internetowy interfejs API z przestrzenią nazw

recaptchaVerifier.render()
  .then(function(widgetId) {
    window.recaptchaWidgetId = widgetId;
  });

Po rozwiązaniu funkcji render() otrzymasz identyfikator widżetu reCAPTCHA, którego możesz użyć do wywołania interfejsu API reCAPTCHA :

var recaptchaResponse = grecaptcha.getResponse(window.recaptchaWidgetId);

RecaptchaVerifier abstrahuje tę logikę za pomocą metody weryfikacji , więc nie musisz bezpośrednio obsługiwać zmiennej grecaptcha .

Rejestracja drugiego czynnika

Aby zapisać nowy dodatkowy czynnik dla użytkownika:

  1. Ponownie uwierzytelnij użytkownika.

  2. Poproś użytkownika o podanie numeru telefonu.

  3. Zainicjuj weryfikator reCAPTCHA, jak pokazano w poprzedniej sekcji. Pomiń ten krok, jeśli instancja RecaptchaVerifier jest już skonfigurowana:

    Modułowe API sieciowe

    import { RecaptchaVerifier } from "firebase/auth";
    
    const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
    

    Internetowy interfejs API z przestrzenią nazw

    var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
    
  4. Uzyskaj sesję wieloczynnikową dla użytkownika:

    Modułowe API sieciowe

    import { multiFactor } from "firebase/auth";
    
    multiFactor(user).getSession().then(function (multiFactorSession) {
        // ...
    });
    

    Internetowy interfejs API z przestrzenią nazw

    user.multiFactor.getSession().then(function(multiFactorSession) {
      // ...
    })
    
  5. Zainicjuj obiekt PhoneInfoOptions numerem telefonu użytkownika i sesją wieloczynnikową:

    Modułowe API sieciowe

    // Specify the phone number and pass the MFA session.
    const phoneInfoOptions = {
      phoneNumber: phoneNumber,
      session: multiFactorSession
    };
    

    Internetowy interfejs API z przestrzenią nazw

    // Specify the phone number and pass the MFA session.
    var phoneInfoOptions = {
      phoneNumber: phoneNumber,
      session: multiFactorSession
    };
    
  6. Wyślij wiadomość weryfikacyjną na telefon użytkownika:

    Modułowe API sieciowe

    import { PhoneAuthProvider } from "firebase/auth";
    
    const phoneAuthProvider = new PhoneAuthProvider(auth);
    phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
        .then(function (verificationId) {
            // verificationId will be needed to complete enrollment.
        });
    

    Internetowy interfejs API z przestrzenią nazw

    var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
    // Send SMS verification code.
    return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
      .then(function(verificationId) {
        // verificationId will be needed for enrollment completion.
      })
    

    Chociaż nie jest to wymagane, najlepszą praktyką jest wcześniejsze poinformowanie użytkowników, że otrzymają wiadomość SMS i że obowiązują standardowe stawki.

  7. Jeśli żądanie nie powiedzie się, zresetuj reCAPTCHA, a następnie powtórz poprzedni krok, aby użytkownik mógł spróbować ponownie. Należy pamiętać, że verifyPhoneNumber() automatycznie zresetuje reCAPTCHA, gdy zgłosi błąd, ponieważ tokeny reCAPTCHA są jednorazowego użytku.

    Modułowe API sieciowe

    recaptchaVerifier.clear();
    

    Internetowy interfejs API z przestrzenią nazw

    recaptchaVerifier.clear();
    
  8. Po wysłaniu kodu SMS poproś użytkownika o weryfikację kodu:

    Modułowe API sieciowe

    // Ask user for the verification code. Then:
    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
    

    Internetowy interfejs API z przestrzenią nazw

    // Ask user for the verification code. Then:
    var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    
  9. Zainicjuj obiekt MultiFactorAssertion za pomocą PhoneAuthCredential :

    Modułowe API sieciowe

    import { PhoneMultiFactorGenerator } from "firebase/auth";
    
    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
    

    Internetowy interfejs API z przestrzenią nazw

    var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
    
  10. Dokończ rejestrację. Opcjonalnie można określić nazwę wyświetlaną dla drugiego czynnika. Jest to przydatne dla użytkowników korzystających z wielu sekund, ponieważ numer telefonu jest maskowany podczas uwierzytelniania (na przykład +1******1234).

    Modułowe API sieciowe

    // Complete enrollment. This will update the underlying tokens
    // and trigger ID token change listener.
    multiFactor(user).enroll(multiFactorAssertion, "My personal phone number");
    

    Internetowy interfejs API z przestrzenią nazw

    // Complete enrollment. This will update the underlying tokens
    // and trigger ID token change listener.
    user.multiFactor.enroll(multiFactorAssertion, 'My personal phone number');
    

Poniższy kod przedstawia pełny przykład rejestracji drugiego czynnika:

Modułowe API sieciowe

import {
    multiFactor, PhoneAuthProvider, PhoneMultiFactorGenerator,
    RecaptchaVerifier
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
multiFactor(user).getSession()
    .then(function (multiFactorSession) {
        // Specify the phone number and pass the MFA session.
        const phoneInfoOptions = {
            phoneNumber: phoneNumber,
            session: multiFactorSession
        };

        const phoneAuthProvider = new PhoneAuthProvider(auth);

        // Send SMS verification code.
        return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier);
    }).then(function (verificationId) {
        // Ask user for the verification code. Then:
        const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
        const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);

        // Complete enrollment.
        return multiFactor(user).enroll(multiFactorAssertion, mfaDisplayName);
    });

Internetowy interfejs API z przestrzenią nazw

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
user.multiFactor.getSession().then(function(multiFactorSession) {
  // Specify the phone number and pass the MFA session.
  var phoneInfoOptions = {
    phoneNumber: phoneNumber,
    session: multiFactorSession
  };
  var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
  // Send SMS verification code.
  return phoneAuthProvider.verifyPhoneNumber(
      phoneInfoOptions, recaptchaVerifier);
})
.then(function(verificationId) {
  // Ask user for the verification code.
  var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
  var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
  // Complete enrollment.
  return user.multiFactor.enroll(multiFactorAssertion, mfaDisplayName);
});

Gratulacje! Pomyślnie zarejestrowałeś drugi czynnik uwierzytelniający dla użytkownika.

Logowanie użytkowników przy użyciu drugiego czynnika

Aby zalogować użytkownika za pomocą dwuskładnikowej weryfikacji SMS:

  1. Zaloguj użytkownika przy użyciu pierwszego czynnika, a następnie wyłap błąd auth/multi-factor-auth-required . Ten błąd zawiera moduł rozpoznawania nazw, wskazówki dotyczące zarejestrowanych drugich czynników i podstawową sesję potwierdzającą, że użytkownik pomyślnie uwierzytelnił się przy użyciu pierwszego czynnika.

    Na przykład, jeśli pierwszym czynnikiem użytkownika był adres e-mail i hasło:

    Modułowe API sieciowe

    import { getAuth, getMultiFactorResolver} from "firebase/auth";
    
    const auth = getAuth();
    signInWithEmailAndPassword(auth, email, password)
        .then(function (userCredential) {
            // User successfully signed in and is not enrolled with a second factor.
        })
        .catch(function (error) {
            if (error.code == 'auth/multi-factor-auth-required') {
                // The user is a multi-factor user. Second factor challenge is required.
                resolver = getMultiFactorResolver(auth, error);
                // ...
            } else if (error.code == 'auth/wrong-password') {
                // Handle other errors such as wrong password.
            }
    });
    

    Internetowy interfejs API z przestrzenią nazw

    firebase.auth().signInWithEmailAndPassword(email, password)
      .then(function(userCredential) {
        // User successfully signed in and is not enrolled with a second factor.
      })
      .catch(function(error) {
        if (error.code == 'auth/multi-factor-auth-required') {
          // The user is a multi-factor user. Second factor challenge is required.
          resolver = error.resolver;
          // ...
        } else if (error.code == 'auth/wrong-password') {
          // Handle other errors such as wrong password.
        } ...
      });
    

    Jeśli pierwszym czynnikiem użytkownika jest dostawca stowarzyszony, taki jak OAuth, SAML lub OIDC, wychwytuj błąd po wywołaniu signInWithPopup() signInWithRedirect() .

  2. Jeśli użytkownik ma zarejestrowanych wiele dodatkowych czynników, zapytaj go, którego z nich użyć:

    Modułowe API sieciowe

    // Ask user which second factor to use.
    // You can get the masked phone number via resolver.hints[selectedIndex].phoneNumber
    // You can get the display name via resolver.hints[selectedIndex].displayName
    
    if (resolver.hints[selectedIndex].factorId ===
        PhoneMultiFactorGenerator.FACTOR_ID) {
        // User selected a phone second factor.
        // ...
    } else if (resolver.hints[selectedIndex].factorId ===
               TotpMultiFactorGenerator.FACTOR_ID) {
        // User selected a TOTP second factor.
        // ...
    } else {
        // Unsupported second factor.
    }
    

    Internetowy interfejs API z przestrzenią nazw

    // Ask user which second factor to use.
    // You can get the masked phone number via resolver.hints[selectedIndex].phoneNumber
    // You can get the display name via resolver.hints[selectedIndex].displayName
    if (resolver.hints[selectedIndex].factorId === firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
      // User selected a phone second factor.
      // ...
    } else if (resolver.hints[selectedIndex].factorId === firebase.auth.TotpMultiFactorGenerator.FACTOR_ID) {
      // User selected a TOTP second factor.
      // ...
    } else {
      // Unsupported second factor.
    }
    
  3. Zainicjuj weryfikator reCAPTCHA, jak pokazano w poprzedniej sekcji. Pomiń ten krok, jeśli instancja RecaptchaVerifier jest już skonfigurowana:

    Modułowe API sieciowe

    import { RecaptchaVerifier } from "firebase/auth";
    
    recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
    

    Internetowy interfejs API z przestrzenią nazw

    var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
    
  4. Zainicjuj obiekt PhoneInfoOptions przy użyciu numeru telefonu użytkownika i sesji wieloskładnikowej. Wartości te są zawarte w obiekcie resolver przekazanym do błędu auth/multi-factor-auth-required :

    Modułowe API sieciowe

    const phoneInfoOptions = {
        multiFactorHint: resolver.hints[selectedIndex],
        session: resolver.session
    };
    

    Internetowy interfejs API z przestrzenią nazw

    var phoneInfoOptions = {
      multiFactorHint: resolver.hints[selectedIndex],
      session: resolver.session
    };
    
  5. Wyślij wiadomość weryfikacyjną na telefon użytkownika:

    Modułowe API sieciowe

    // Send SMS verification code.
    const phoneAuthProvider = new PhoneAuthProvider(auth);
    phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
        .then(function (verificationId) {
            // verificationId will be needed for sign-in completion.
        });
    

    Internetowy interfejs API z przestrzenią nazw

    var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
    // Send SMS verification code.
    return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
      .then(function(verificationId) {
        // verificationId will be needed for sign-in completion.
      })
    
  6. Jeśli żądanie nie powiedzie się, zresetuj reCAPTCHA, a następnie powtórz poprzedni krok, aby użytkownik mógł spróbować ponownie:

    Modułowe API sieciowe

    recaptchaVerifier.clear();
    

    Internetowy interfejs API z przestrzenią nazw

    recaptchaVerifier.clear();
    
  7. Po wysłaniu kodu SMS poproś użytkownika o weryfikację kodu:

    Modułowe API sieciowe

    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
    

    Internetowy interfejs API z przestrzenią nazw

    // Ask user for the verification code. Then:
    var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    
  8. Zainicjuj obiekt MultiFactorAssertion za pomocą PhoneAuthCredential :

    Modułowe API sieciowe

    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
    

    Internetowy interfejs API z przestrzenią nazw

    var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
    
  9. Wywołaj resolver.resolveSignIn() , aby dokończyć uwierzytelnianie dodatkowe. Następnie możesz uzyskać dostęp do pierwotnego wyniku logowania, który obejmuje standardowe dane specyficzne dla dostawcy i poświadczenia uwierzytelniające:

    Modułowe API sieciowe

    // Complete sign-in. This will also trigger the Auth state listeners.
    resolver.resolveSignIn(multiFactorAssertion)
        .then(function (userCredential) {
            // userCredential will also contain the user, additionalUserInfo, optional
            // credential (null for email/password) associated with the first factor sign-in.
    
            // For example, if the user signed in with Google as a first factor,
            // userCredential.additionalUserInfo will contain data related to Google
            // provider that the user signed in with.
            // - user.credential contains the Google OAuth credential.
            // - user.credential.accessToken contains the Google OAuth access token.
            // - user.credential.idToken contains the Google OAuth ID token.
        });
    

    Internetowy interfejs API z przestrzenią nazw

    // Complete sign-in. This will also trigger the Auth state listeners.
    resolver.resolveSignIn(multiFactorAssertion)
      .then(function(userCredential) {
        // userCredential will also contain the user, additionalUserInfo, optional
        // credential (null for email/password) associated with the first factor sign-in.
        // For example, if the user signed in with Google as a first factor,
        // userCredential.additionalUserInfo will contain data related to Google provider that
        // the user signed in with.
        // user.credential contains the Google OAuth credential.
        // user.credential.accessToken contains the Google OAuth access token.
        // user.credential.idToken contains the Google OAuth ID token.
      });
    

Poniższy kod przedstawia pełny przykład logowania użytkownika wieloskładnikowego:

Modułowe API sieciowe

import {
    getAuth,
    getMultiFactorResolver,
    PhoneAuthProvider,
    PhoneMultiFactorGenerator,
    RecaptchaVerifier,
    signInWithEmailAndPassword
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);

const auth = getAuth();
signInWithEmailAndPassword(auth, email, password)
    .then(function (userCredential) {
        // User is not enrolled with a second factor and is successfully
        // signed in.
        // ...
    })
    .catch(function (error) {
        if (error.code == 'auth/multi-factor-auth-required') {
            const resolver = getMultiFactorResolver(auth, error);
            // Ask user which second factor to use.
            if (resolver.hints[selectedIndex].factorId ===
                PhoneMultiFactorGenerator.FACTOR_ID) {
                const phoneInfoOptions = {
                    multiFactorHint: resolver.hints[selectedIndex],
                    session: resolver.session
                };
                const phoneAuthProvider = new PhoneAuthProvider(auth);
                // Send SMS verification code
                return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
                    .then(function (verificationId) {
                        // Ask user for the SMS verification code. Then:
                        const cred = PhoneAuthProvider.credential(
                            verificationId, verificationCode);
                        const multiFactorAssertion =
                            PhoneMultiFactorGenerator.assertion(cred);
                        // Complete sign-in.
                        return resolver.resolveSignIn(multiFactorAssertion)
                    })
                    .then(function (userCredential) {
                        // User successfully signed in with the second factor phone number.
                    });
            } else if (resolver.hints[selectedIndex].factorId ===
                       TotpMultiFactorGenerator.FACTOR_ID) {
                // Handle TOTP MFA.
                // ...
            } else {
                // Unsupported second factor.
            }
        } else if (error.code == 'auth/wrong-password') {
            // Handle other errors such as wrong password.
        }
    });

Internetowy interfejs API z przestrzenią nazw

var resolver;
firebase.auth().signInWithEmailAndPassword(email, password)
  .then(function(userCredential) {
    // User is not enrolled with a second factor and is successfully signed in.
    // ...
  })
  .catch(function(error) {
    if (error.code == 'auth/multi-factor-auth-required') {
      resolver = error.resolver;
      // Ask user which second factor to use.
      if (resolver.hints[selectedIndex].factorId ===
          firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
        var phoneInfoOptions = {
          multiFactorHint: resolver.hints[selectedIndex],
          session: resolver.session
        };
        var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
        // Send SMS verification code
        return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
          .then(function(verificationId) {
            // Ask user for the SMS verification code.
            var cred = firebase.auth.PhoneAuthProvider.credential(
                verificationId, verificationCode);
            var multiFactorAssertion =
                firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
            // Complete sign-in.
            return resolver.resolveSignIn(multiFactorAssertion)
          })
          .then(function(userCredential) {
            // User successfully signed in with the second factor phone number.
          });
      } else if (resolver.hints[selectedIndex].factorId ===
        firebase.auth.TotpMultiFactorGenerator.FACTOR_ID) {
        // Handle TOTP MFA.
        // ...
      } else {
        // Unsupported second factor.
      }
    } else if (error.code == 'auth/wrong-password') {
      // Handle other errors such as wrong password.
    } ...
  });

Gratulacje! Pomyślnie zalogowałeś użytkownika przy użyciu uwierzytelniania wieloskładnikowego.

Co dalej