Dodawanie uwierzytelniania wielopoziomowego TOTP do aplikacji na iOS

Po przejściu na Uwierzytelnianie Firebase z Identity Platform możesz dodać hasło jednorazowe na czas. uwierzytelnianie wielopoziomowe (MFA) aplikacji (TOTP).

Uwierzytelnianie Firebase na platformie Identity Platform umożliwia stosowanie TOTP jako dodatkowego czynnika uwierzytelniania MFA. Gdy włącz tę funkcję, użytkownicy próbujący zalogować się w Twojej aplikacji zobaczą TOTP. Aby go wygenerować, musi użyć aplikacji uwierzytelniającej, która potrafi wygenerować prawidłowe kody TOTP, np. Google Authenticator.

Zanim zaczniesz

  1. Włącz co najmniej 1 dostawcę, który obsługuje MFA. Pamiętaj, że wszyscy dostawcy oprócz tych obsługujących MFA:

    • Uwierzytelnianie telefonu
    • Anonimowe uwierzytelnianie
    • Niestandardowe tokeny uwierzytelniania
    • Apple Game Center
  2. Upewnij się, że aplikacja weryfikuje adresy e-mail użytkowników. MFA wymaga adresu e-mail weryfikacji. Dzięki temu hakerzy nie będą mogli zarejestrować się w usłudze za pomocą cudzego adresu e-mail, a następnie zablokować właściciela adresu e-mail, dodając drugi składnik.

  3. Zainstaluj Pakiet SDK Firebase Apple.

    Protokół TOTP MFA jest obsługiwany tylko w Apple SDK w wersji 10.12.0 i nowszych, tylko na iOS.

Włącz TOTP MFA

Aby włączyć TOTP jako drugi czynnik, użyj pakietu Admin SDK lub wywołaj projekt konfiguracji punktu końcowego REST.

Aby używać pakietu Admin SDK, wykonaj te czynności:

  1. Zainstaluj Pakiet SDK Firebase Admin Node.js.

    Protokół TOTP MFA jest obsługiwany tylko przez pakiet SDK Firebase Admin Node.js w wersji 11.6.0 oraz powyżej.

  2. Wykonaj zapytanie:

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

    Zastąp następujące elementy:

    • NUM_ADJ_INTERVALS: liczba sąsiadujących ze sobą przedziały czasu, w których mają być akceptowane hasła TOTP, od 0 do 10. domyślna wartość to 5.

      Skrypty TOTP działają tak, aby, gdy dwie strony (zalecający i walidatorowi) generować hasła jednorazowe w tym samym przedziale czasu (zwykle 30 sekund, generują to samo hasło. Jednak aby dostosować jeśli występują różnice między podmiotami a czasem reakcji ludzi, możesz skonfigurować TOTP aby akceptować także TOTP z sąsiednich okien.

Aby włączyć TOTP MFA za pomocą interfejsu API REST, uruchom to polecenie:

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

Zastąp następujące elementy:

  • PROJECT_ID: identyfikator projektu.
  • NUM_ADJ_INTERVALS: liczba przedziałów czasu w odstępach czasowych od 0 do 10. Wartością domyślną jest 5.

    Skrypty TOTP działają tak, aby, gdy dwie strony (zalecający i walidatorowi) generować hasła jednorazowe w tym samym przedziale czasu (zwykle 30 sekund, generują to samo hasło. Jednak aby dostosować jeśli występują różnice między podmiotami a czasem reakcji ludzi, możesz skonfigurować TOTP aby akceptować także TOTP z sąsiednich okien.

Wybierz wzorzec rejestracji

Możesz zdecydować, czy Twoja aplikacja wymaga uwierzytelniania wielopoziomowego i w jaki sposób i kiedy zarejestrować użytkowników. Oto niektóre typowe wzorce:

  • Zarejestruj drugi składnik logowania użytkownika w ramach rejestracji. Użyj tej , jeśli Twoja aplikacja wymaga uwierzytelniania wielopoziomowego dla wszystkich użytkowników.

  • Zaoferować możliwą do pominięcia opcję rejestracji drugiego składnika podczas rejestracji. Jeśli chcesz zachęcić do uwierzytelniania wielopoziomowego w aplikacji, ale nie wymagać od Ciebie jej stosowania, może zastosować tę metodę.

  • umożliwia dodanie drugiego składnika z konta lub profilu użytkownika. na stronie zarządzania, a nie na ekranie rejestracji. Pozwala to zminimalizować tarcie podczas rejestracji, a jednocześnie stosować uwierzytelnianie dwuskładnikowe. dostępna dla użytkowników, którzy zwracają uwagę na bezpieczeństwo.

  • Wymagaj stopniowego dodawania drugiego składnika, gdy użytkownik chce uzyskać dostęp funkcje o wyższych wymaganiach w zakresie bezpieczeństwa.

Rejestrowanie użytkowników w TOTP MFA

Po włączeniu protokołu TOTP MFA jako drugiego składnika w aplikacji wdróż konfigurację po stronie klienta logic do rejestrowania użytkowników w TOTP MFA:

  1. Ponownie uwierzytelnij użytkownika.

  2. Wygeneruj tajny klucz TOTP dla uwierzytelnionego użytkownika:

    // 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. Wyświetl użytkownikowi tajny klucz i poproś go o jego podanie aplikacja uwierzytelniająca:

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

    Oprócz wyświetlenia tajnego klucza możesz spróbować automatycznie dodaj go do domyślnej aplikacji uwierzytelniającej na urządzeniu. Aby to zrobić, wygeneruj plik identyfikator URI klucza zgodny z Google Authenticator, i przekaż ją openInOTPApp(withQRCodeURL:):

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

    Gdy użytkownik doda swój tajny klucz do aplikacji uwierzytelniającej, zostanie uruchomiony i generowanie tagów TOTP.

  4. użytkownik musi wpisać TOTP wyświetlony w aplikacji uwierzytelniającej, użyj go, aby zakończyć rejestrację MFA:

    // 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.
    }
    

Logowanie użytkowników za pomocą drugiego składnika

Aby zalogować użytkowników za pomocą TOTP MFA, użyj tego kodu:

  1. Wywołaj jedną z metod signIn(with...:) w taki sam sposób, jak w przypadku innej opcji używając MFA (np. signIn(withEmail:password:)). Jeśli metoda zgłasza błąd z kodem secondFactorRequired, uruchom proces MFA aplikacji.

    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. Procedura MFA aplikacji powinna najpierw zachęcić użytkownika do wyboru drugiego składnika których nie chce używać. Listę obsługiwanych drugich czynników możesz sprawdzić, badanie właściwości hints instancji MultiFactorResolver:

    let mfaKey = AuthErrorUserInfoMultiFactorResolverKey
    guard let resolver = error.userInfo[mfaKey] as? MultiFactorResolver else { return }
    let enrolledFactors = resolver.hints.map(\.displayName)
    
  3. Jeśli użytkownik zdecyduje się na użycie protokołu TOTP, poproś go o wpisanie tagu TOTP wyświetlanego na stronie jej aplikację uwierzytelniającą i użyć jej do zalogowania się:

    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
    }
    

Wyrejestruj się z TOTP MFA

Ta sekcja zawiera informacje o tym, jak postępować w przypadku użytkownika wyrejestrującego się z TOTP MFA.

Jeśli użytkownik zarejestrował się w wielu opcjach MFA i jeśli się wyrejestrował wybierając spośród ostatnio włączonej opcji, otrzyma auth/user-token-expired i są wylogowani. Użytkownik będzie musiał zalogować się ponownie i potwierdzić swoje konto istniejących danych logowania, takich jak adres e-mail i hasło.

Aby wyrejestrować użytkownika, naprawić błąd i aktywować ponowne uwierzytelnianie, skorzystaj z ten kod:

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

Co dalej?