TOTP-Multi-Faktor-Authentifizierung für Ihre iOS-App hinzufügen

Wenn Sie ein Upgrade auf Firebase Authentication with Identity Platform durchgeführt haben, können Sie Ihrer App die Multi-Faktor-Authentifizierung (MFA) mit zeitbasierten Einmalpasswörtern (TOTP) hinzufügen.

Mit Firebase Authentication with Identity Platform können Sie ein TOTP als zusätzlichen Faktor für die MFA verwenden. Wenn Sie diese Funktion aktivieren, wird Nutzern, die sich in Ihrer App anmelden möchten, eine Aufforderung zur Eingabe eines TOTP angezeigt. Dazu müssen sie eine Authentifizierungs-App verwenden, die gültige TOTP-Codes generieren kann, z. B. Google Authenticator.

Hinweis

  1. Aktivieren Sie mindestens einen Anbieter, der die MFA unterstützt. Hinweis: Alle Anbieter außer den folgenden unterstützen die MFA:

    • Authentifizierung per Telefon
    • Anonyme Authentifizierung
    • Benutzerdefinierte Authentifizierungstokens
    • Apple Game Center
  2. Sorgen Sie dafür, dass die E-Mail-Adressen der Nutzer in Ihrer App bestätigt werden. Für die MFA ist eine E-Mail-Bestätigung erforderlich. So wird 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 Inhaber der E‑Mail-Adresse durch Hinzufügen eines zweiten Faktors aussperren.

  3. Installieren Sie das Firebase Apple SDK, falls noch nicht geschehen.

    Die TOTP-MFA wird nur ab Apple SDK-Version 10.12.0 und nur unter iOS unterstützt.

TOTP-MFA aktivieren

Wenn Sie TOTP als zweiten Faktor aktivieren möchten, verwenden Sie die Admin SDK oder rufen Sie den REST-Endpunkt für die Projektkonfiguration auf.

So verwenden Sie die Admin SDK:

  1. Installieren Sie das Firebase Admin Node.js SDK, falls noch nicht geschehen.

    TOTP-MFA wird nur in Firebase Admin Node.js SDK-Versionen ab 11.6.0 unterstützt.

  2. Führen Sie den folgenden Befehl aus:

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

    Ersetzen Sie Folgendes:

    • NUM_ADJ_INTERVALS: Die Anzahl der benachbarten Zeitfensterintervalle, aus denen TOTPs akzeptiert werden, von null bis zehn. Der Standardwert ist fünf.

      TOTPs funktionieren so, dass zwei Parteien (der Prüfer und der Validator) innerhalb desselben Zeitfensters (normalerweise 30 Sekunden) OTPs generieren und dabei dasselbe Passwort erzeugen. Um jedoch die Zeitabweichung zwischen den Parteien und die menschliche Reaktionszeit zu berücksichtigen, können Sie den TOTP-Dienst so konfigurieren, dass er auch TOTPs aus benachbarten Fenstern akzeptiert.

Führen Sie den folgenden Befehl aus, um die TOTP-MFA mit der REST API zu aktivieren:

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

Ersetzen Sie Folgendes:

  • PROJECT_ID: die Projekt-ID
  • NUM_ADJ_INTERVALS: Die Anzahl der Zeitfensterintervalle, von null bis zehn. Der Standardwert ist fünf.

    TOTPs funktionieren so, dass zwei Parteien (der Prüfer und der Validator) innerhalb desselben Zeitfensters (normalerweise 30 Sekunden) OTPs generieren und dabei dasselbe Passwort erzeugen. Um jedoch die Zeitabweichung zwischen den Parteien und die menschliche Reaktionszeit zu berücksichtigen, können Sie den TOTP-Dienst so konfigurieren, dass er auch TOTPs aus benachbarten Fenstern akzeptiert.

Registrierungsmuster auswählen

Sie können auswählen, ob Ihre Anwendung eine Multi-Faktor-Authentifizierung erfordert, und wie und wann Ihre Nutzer registriert werden sollen. Zu den gängigen Mustern gehören:

  • Bieten Sie den zweiten Faktor des Nutzers als Teil der Registrierung an. Verwenden Sie diese Methode, wenn Ihre Anwendung eine Multi-Faktor-Authentifizierung für alle Nutzer erfordert.

  • Bieten Sie bei der Registrierung eine überspringbare Option an, mit der ein zweiter Faktor registriert werden kann. Wenn Sie die Multi-Faktor-Authentifizierung in Ihrer Anwendung fördern, aber nicht vorschreiben möchten, können Sie diesen Ansatz verwenden.

  • Bieten Sie die Möglichkeit, einen zweiten Faktor über die Konto- oder Profilverwaltungsseite des Nutzers hinzuzufügen, anstatt über den Anmeldebildschirm. Dadurch wird der Registrierungsprozess vereinfacht und gleichzeitig die Multi-Faktor-Authentifizierung für sicherheitsorientierte Nutzer verfügbar gemacht.

  • Das Hinzufügen eines zweiten Faktors ist erforderlich, wenn der Nutzer auf Features mit höheren Sicherheitsanforderungen zugreifen möchte.

Nutzer für TOTP-MFA registrieren

Nachdem Sie TOTP-MFA als zweiten Faktor für Ihre Anwendung aktiviert haben, implementieren Sie die clientseitige Logik, um Nutzer für TOTP-MFA zu registrieren:

  1. Authentifizieren Sie den Nutzer noch einmal.

  2. Generieren Sie ein TOTP-Secret für den authentifizierten Nutzer:

    // Generate a TOTP secret.
    guard let mfaSession = try? await currentUser.multiFactor.session() else { return }
    guard let totpSecret = try? await TOTPMultiFactorGenerator.generateSecret(with: mfaSession) else { return }
    
    // Display the secret to the user and prompt them to enter it into their
    // authenticator app. (See the next step.)
    
  3. Zeigen Sie dem Nutzer den Secret Key an und fordern Sie ihn auf, ihn in seine Authentifizierungs-App einzugeben:

    // Display this key:
    let secret = totpSecret.sharedSecretKey()
    

    Zusätzlich zur Anzeige des geheimen Schlüssels können Sie versuchen, ihn automatisch der Standard-Authentifizierungs-App des Geräts hinzuzufügen. Generieren Sie dazu einen mit Google Authenticator kompatiblen Schlüssel-URI und übergeben Sie ihn an openInOTPApp(withQRCodeURL:):

    let otpAuthUri = totpSecret.generateQRCodeURL(
        withAccountName: currentUser.email ?? "default account",
        issuer: "Your App Name")
    totpSecret.openInOTPApp(withQRCodeURL: otpAuthUri)
    

    Nachdem der Nutzer das Secret seiner Authentifizierungs-App hinzugefügt hat, werden TOTPs generiert.

  4. Fordern Sie den Nutzer auf, das von seiner Authentifizierungs-App angezeigte TOTP einzugeben und damit die MFA-Registrierung abzuschließen:

    // Ask the user for a verification code from the authenticator app.
    let verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    let multiFactorAssertion = TOTPMultiFactorGenerator.assertionForEnrollment(
        with: totpSecret,
        oneTimePassword: verificationCode)
    do {
        try await currentUser.multiFactor.enroll(
            with: multiFactorAssertion,
            displayName: "TOTP")
    } catch {
        // Wrong or expired OTP. Re-prompt the user.
    }
    

Nutzer mit einem zweiten Faktor anmelden

Verwenden Sie den folgenden Code, um Nutzer mit TOTP-MFA anzumelden:

  1. Rufen Sie eine der signIn(with...:)-Methoden auf, so wie Sie es tun würden, wenn Sie keine 2FA verwenden würden (z. B. signIn(withEmail:password:)). Wenn die Methode einen Fehler mit dem Code secondFactorRequired ausgibt, starten Sie den 2FA-Ablauf Ihrer App.

    do {
        let authResult = try await Auth.auth().signIn(withEmail: email, password: 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 let error as AuthErrorCode where error.code == .secondFactorRequired {
        // Initiate your second factor sign-in flow. (See next step.)
        // ...
    } catch {
        // Other auth error.
        throw error
    }
    
  2. Im MFA-Ablauf Ihrer App sollte der Nutzer zuerst aufgefordert werden, den zweiten Faktor auszuwählen, den er verwenden möchte. Sie können eine Liste der unterstützten zweiten Faktoren abrufen, indem Sie das Attribut hints einer MultiFactorResolver-Instanz prüfen:

    let mfaKey = AuthErrorUserInfoMultiFactorResolverKey
    guard let resolver = error.userInfo[mfaKey] as? MultiFactorResolver else { return }
    let enrolledFactors = resolver.hints.map(\.displayName)
    
  3. Wenn der Nutzer TOTP verwenden möchte, fordere ihn auf, das in seiner Authentifizierungs-App angezeigte TOTP einzugeben und sich damit anzumelden:

    let multiFactorInfo = resolver.hints[selectedIndex]
    switch multiFactorInfo.factorID {
    case TOTPMultiFactorID:
        let otpFromAuthenticator = // OTP typed by the user.
        let assertion = TOTPMultiFactorGenerator.assertionForSignIn(
            withEnrollmentID: multiFactorInfo.uid,
            oneTimePassword: otpFromAuthenticator)
        do {
            let authResult = try await resolver.resolveSignIn(with: assertion)
        } catch {
            // Wrong or expired OTP. Re-prompt the user.
        }
    default:
        return
    }
    

Von TOTP-MFA abmelden

In diesem Abschnitt wird beschrieben, wie Sie vorgehen, wenn ein Nutzer die TOTP-MFA abmeldet.

Wenn sich ein Nutzer für mehrere MFA-Optionen registriert hat und sich von der zuletzt aktivierten Option abmeldet, erhält er eine auth/user-token-expired und wird abgemeldet. Der Nutzer muss sich noch einmal anmelden und seine vorhandenen Anmeldedaten bestätigen, z. B. eine E‑Mail-Adresse und ein Passwort.

Verwenden Sie den folgenden Code, um den Nutzer abzumelden, den Fehler zu beheben und die erneute Authentifizierung auszulösen:

guard let currentUser = Auth.auth().currentUser else { return }

// Prompt the user to select a factor to unenroll, from this array:
currentUser.multiFactor.enrolledFactors

// ...

// Unenroll the second factor.
let multiFactorInfo = currentUser.multiFactor.enrolledFactors[selectedIndex]
do {
    try await currentUser.multiFactor.unenroll(with: multiFactorInfo)
} catch let error as AuthErrorCode where error.code == .invalidUserToken {
    // Second factor unenrolled, but the user was signed out. Re-authenticate
    // them.
}

Nächste Schritte