Fügen Sie Ihrer Flutter-App eine Multi-Faktor-Authentifizierung hinzu

Wenn Sie ein Upgrade auf Firebase Authentication mit Identity Platform durchgeführt haben, können Sie Ihrer Flutter-App eine mehrstufige SMS-Authentifizierung hinzufügen.

Die Multi-Faktor-Authentifizierung (MFA) erhöht die Sicherheit Ihrer App. Während Angreifer häufig Passwörter und soziale Konten kompromittieren, ist das Abfangen einer Textnachricht schwieriger.

Bevor Sie beginnen

  1. Aktivieren Sie mindestens einen Anbieter, der die Multi-Faktor-Authentifizierung unterstützt. Jeder Anbieter unterstützt MFA, außer Telefonauthentifizierung, anonyme Authentifizierung und Apple Game Center.

  2. Stellen Sie sicher, dass Ihre App die E-Mails der Benutzer überprüft. MFA erfordert eine E-Mail-Bestätigung. Dies verhindert, dass sich böswillige Akteure mit einer E-Mail-Adresse, die ihnen nicht gehört, für einen Dienst registrieren und dann den tatsächlichen Eigentümer ausschließen, indem sie einen zweiten Faktor hinzufügen.

  3. Android : Wenn Sie den SHA-256-Hash Ihrer App noch nicht in der Firebase-Konsole festgelegt haben, tun Sie dies. Informationen zum Ermitteln des SHA-256-Hashs Ihrer App finden Sie unter Authentifizieren Ihres Clients .

  4. iOS : Aktivieren Sie in Xcode Push-Benachrichtigungen für Ihr Projekt und stellen Sie sicher, dass Ihr APNs-Authentifizierungsschlüssel mit Firebase Cloud Messaging (FCM) konfiguriert ist. Darüber hinaus müssen Sie Hintergrundmodi für Remote-Benachrichtigungen aktivieren . Eine ausführliche Erläuterung dieses Schritts finden Sie in der Dokumentation zur Firebase iOS Phone Auth .

  5. Web : Stellen Sie sicher, dass Sie Ihre Anwendungsdomäne in der Firebase-Konsole unter „OAuth-Umleitungsdomänen“ hinzugefügt haben.

Multi-Faktor-Authentifizierung aktivieren

  1. Öffnen Sie die Seite Authentifizierung > Anmeldemethode der Firebase-Konsole.

  2. Aktivieren Sie im Abschnitt „Erweitert“ die SMS-Multifaktor-Authentifizierung .

    Sie sollten auch die Telefonnummern eingeben, mit denen Sie Ihre App testen möchten. Die Registrierung von Testtelefonnummern ist zwar optional, wird jedoch dringend empfohlen, um eine Drosselung während der Entwicklung zu vermeiden.

  3. Wenn Sie die Domäne Ihrer App noch nicht autorisiert haben, fügen Sie sie der Zulassungsliste auf der Seite „Authentifizierung“ > „Einstellungen“ der Firebase-Konsole hinzu.

Auswählen eines Anmeldemusters

Sie können wählen, ob Ihre App eine Multi-Faktor-Authentifizierung erfordert und wie und wann Sie Ihre Benutzer registrieren. Einige häufige Muster sind:

  • Registrieren Sie den zweiten Faktor des Benutzers im Rahmen der Registrierung. Verwenden Sie diese Methode, wenn Ihre App eine mehrstufige Authentifizierung für alle Benutzer erfordert.

  • Bieten Sie bei der Registrierung eine überspringbare Option zur Registrierung eines zweiten Faktors an. Apps, die die Multi-Faktor-Authentifizierung fördern, aber nicht erfordern möchten, bevorzugen möglicherweise diesen Ansatz.

  • Bieten Sie die Möglichkeit, einen zweiten Faktor über die Konto- oder Profilverwaltungsseite des Benutzers anstelle des Anmeldebildschirms hinzuzufügen. Dies minimiert die Reibung während des Registrierungsprozesses und stellt gleichzeitig die Multi-Faktor-Authentifizierung für sicherheitsempfindliche Benutzer zur Verfügung.

  • Erfordern Sie das schrittweise Hinzufügen eines zweiten Faktors, wenn der Benutzer auf Funktionen mit erhöhten Sicherheitsanforderungen zugreifen möchte.

Einschreiben eines zweiten Faktors

So registrieren Sie einen neuen sekundären Faktor für einen Benutzer:

  1. Authentifizieren Sie den Benutzer erneut.

  2. Bitten Sie den Benutzer, seine Telefonnummer einzugeben.

  3. Holen Sie sich eine Multi-Faktor-Sitzung für den Benutzer:

    final multiFactorSession = await user.multiFactor.getSession();
    
  4. Überprüfen Sie die Telefonnummer mit einer Multi-Faktor-Sitzung und Ihren Rückrufen:

    await FirebaseAuth.instance.verifyPhoneNumber(
      multiFactorSession: multiFactorSession,
      phoneNumber: phoneNumber,
      verificationCompleted: (_) {},
      verificationFailed: (_) {},
      codeSent: (String verificationId, int? resendToken) async {
        // The SMS verification code has been sent to the provided phone number.
        // ...
      },
      codeAutoRetrievalTimeout: (_) {},
    ); 
    
  5. Sobald der SMS-Code gesendet wurde, bitten Sie den Benutzer, den Code zu bestätigen:

    final credential = PhoneAuthProvider.credential(
      verificationId: verificationId,
      smsCode: smsCode,
    );
    
  6. Vervollständigen Sie die Anmeldung:

    await user.multiFactor.enroll(
      PhoneMultiFactorGenerator.getAssertion(
        credential,
      ),
    );
    

Der folgende Code zeigt ein vollständiges Beispiel für die Registrierung eines zweiten Faktors:

  final session = await user.multiFactor.getSession();
  final auth = FirebaseAuth.instance;
  await auth.verifyPhoneNumber(
    multiFactorSession: session,
    phoneNumber: phoneController.text,
    verificationCompleted: (_) {},
    verificationFailed: (_) {},
    codeSent: (String verificationId, int? resendToken) async {
      // See `firebase_auth` example app for a method of retrieving user's sms code: 
      // https://github.com/firebase/flutterfire/blob/master/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
      final smsCode = await getSmsCodeFromUser(context);

      if (smsCode != null) {
        // Create a PhoneAuthCredential with the code
        final credential = PhoneAuthProvider.credential(
          verificationId: verificationId,
          smsCode: smsCode,
        );

        try {
          await user.multiFactor.enroll(
            PhoneMultiFactorGenerator.getAssertion(
              credential,
            ),
          );
        } on FirebaseAuthException catch (e) {
          print(e.message);
        }
      }
    },
    codeAutoRetrievalTimeout: (_) {},
  );

Glückwunsch! Sie haben erfolgreich einen zweiten Authentifizierungsfaktor für einen Benutzer registriert.

Benutzer mit einem zweiten Faktor anmelden

So melden Sie einen Benutzer mit der Zwei-Faktor-SMS-Verifizierung an:

  1. Melden Sie den Benutzer mit seinem ersten Faktor an und fangen Sie dann die FirebaseAuthMultiFactorException Ausnahme ab. Dieser Fehler enthält einen Resolver, mit dem Sie die registrierten zweiten Faktoren des Benutzers abrufen können. Es enthält auch eine zugrunde liegende Sitzung, die beweist, dass sich der Benutzer erfolgreich mit seinem ersten Faktor authentifiziert hat.

    Wenn der erste Faktor des Benutzers beispielsweise eine E-Mail-Adresse und ein Passwort wäre:

    try {
      await _auth.signInWithEmailAndPassword(
          email: emailController.text,
          password: passwordController.text,
      );
      // User is not enrolled with a second factor and is successfully
      // signed in.
      // ...
    } on FirebaseAuthMultiFactorException catch (e) {
      // The user is a multi-factor user. Second factor challenge is required
      final resolver = e.resolver
      // ...
    }
    
  2. Wenn der Benutzer mehrere sekundäre Faktoren registriert hat, fragen Sie ihn, welchen er verwenden soll:

    final session = e.resolver.session;
    
    final hint = e.resolver.hints[selectedHint];
    
  3. Senden Sie eine Bestätigungsnachricht mit dem Hinweis und der Multi-Faktor-Sitzung an das Telefon des Benutzers:

    await FirebaseAuth.instance.verifyPhoneNumber(
      multiFactorSession: session,
      multiFactorInfo: hint,
      verificationCompleted: (_) {},
      verificationFailed: (_) {},
      codeSent: (String verificationId, int? resendToken) async {
        // ...
      },
      codeAutoRetrievalTimeout: (_) {},
    );
    
  4. Rufen Sie resolver.resolveSignIn() auf, um die sekundäre Authentifizierung abzuschließen:

    final smsCode = await getSmsCodeFromUser(context);
    if (smsCode != null) {
      // Create a PhoneAuthCredential with the code
      final credential = PhoneAuthProvider.credential(
        verificationId: verificationId,
        smsCode: smsCode,
      );
    
      try {
        await e.resolver.resolveSignIn(
          PhoneMultiFactorGenerator.getAssertion(credential)
        );
      } on FirebaseAuthException catch (e) {
        print(e.message);
      }
    }
    

Der folgende Code zeigt ein vollständiges Beispiel für die Anmeldung eines Multi-Faktor-Benutzers:

try {
  await _auth.signInWithEmailAndPassword(
    email: emailController.text,
    password: passwordController.text,
  );
} on FirebaseAuthMultiFactorException catch (e) {
  setState(() {
    error = '${e.message}';
  });
  final firstHint = e.resolver.hints.first;
  if (firstHint is! PhoneMultiFactorInfo) {
    return;
  }
  await FirebaseAuth.instance.verifyPhoneNumber(
    multiFactorSession: e.resolver.session,
    multiFactorInfo: firstHint,
    verificationCompleted: (_) {},
    verificationFailed: (_) {},
    codeSent: (String verificationId, int? resendToken) async {
      // See `firebase_auth` example app for a method of retrieving user's sms code: 
      // https://github.com/firebase/flutterfire/blob/master/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
      final smsCode = await getSmsCodeFromUser(context);

      if (smsCode != null) {
        // Create a PhoneAuthCredential with the code
        final credential = PhoneAuthProvider.credential(
          verificationId: verificationId,
          smsCode: smsCode,
        );

        try {
          await e.resolver.resolveSignIn(
            PhoneMultiFactorGenerator.getAssertion(
              credential,
            ),
          );
        } on FirebaseAuthException catch (e) {
          print(e.message);
        }
      }
    },
    codeAutoRetrievalTimeout: (_) {},
  );
} catch (e) {
  ...
} 

Glückwunsch! Sie haben einen Benutzer erfolgreich mithilfe der Multi-Faktor-Authentifizierung angemeldet.

Was kommt als nächstes