iOS uygulamanıza TOTP çok öğeli kimlik doğrulaması ekleyin

Firebase Authentication with Identity Platform'a yükseltme yaptıysanız uygulamanıza zaman tabanlı tek kullanımlık şifre (TOTP) çok öğeli kimlik doğrulaması (MFA) ekleyebilirsiniz.

Kimlik Platformu ile Firebase Kimlik Doğrulaması, MFA için ek bir faktör olarak TOTP kullanmanıza olanak tanır. Bu özelliği etkinleştirdiğinizde, uygulamanızda oturum açmaya çalışan kullanıcılar bir TOTP isteği görür. Bunları oluşturmak için, geçerli TOTP kodları oluşturabilen Google Authenticator gibi bir kimlik doğrulayıcı uygulaması kullanmalıdır.

Başlamadan önce

  1. MFA'yı destekleyen en az bir sağlayıcıyı etkinleştirin. Aşağıdakiler hariç tüm sağlayıcıların MFA'yı desteklediğini unutmayın:

    • Telefonla kimlik doğrulama
    • Anonim kimlik doğrulama
    • Özel kimlik doğrulama jetonları
    • Apple Oyun Merkezi
  2. Uygulamanızın kullanıcı e-posta adreslerini doğruladığından emin olun. MFA için e-posta doğrulaması gerekir. Bu, kötü amaçlı kişilerin sahip olmadıkları bir e-posta adresiyle bir hizmete kaydolmalarını ve ardından ikinci bir faktör ekleyerek e-posta adresinin gerçek sahibini ele geçirmelerini önler.

  3. Henüz yapmadıysanız Firebase Apple SDK'sını yükleyin.

    TOTP MFA, yalnızca Apple SDK v10.12.0 ve üzeri sürümlerde ve yalnızca iOS'te desteklenir.

TOTP MFA'yı etkinleştir

İkinci faktör olarak TOTP'yi etkinleştirmek için Yönetici SDK'sını kullanın veya proje yapılandırması REST uç noktasını çağırın.

Yönetici SDK'sini kullanmak için aşağıdakileri yapın:

  1. Henüz yapmadıysanız Firebase Admin Node.js SDK'sını yükleyin.

    TOTP MFA, yalnızca Firebase Admin Node.js SDK'sının 11.6.0 ve üzeri sürümlerinde desteklenir.

  2. Aşağıdaki komutu çalıştırın:

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

    Aşağıdakini değiştirin:

    • NUM_ADJ_INTERVALS: TOTP'lerin kabul edileceği, sıfırdan ona kadar olan bitişik zaman aralığı aralıklarının sayısı. Varsayılan değer beştir.

      TOTP'ler, iki tarafın (kanıtlayıcı ve doğrulayıcı) aynı zaman aralığı içinde (genellikle 30 saniye uzunluğunda) OTP'leri oluşturduklarında aynı şifreyi oluşturmalarını sağlayarak çalışır. Bununla birlikte, taraflar arasındaki saat kaymasını ve gerçek kişilerin yanıt süresini hesaba katmak için TOTP hizmetini, bitişik pencerelerden gelen TOTP'leri de kabul edecek şekilde yapılandırabilirsiniz.

REST API'yi kullanarak TOTP MFA'yı etkinleştirmek için aşağıdaki komutu çalıştırın:

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

Aşağıdakini değiştirin:

  • PROJECT_ID: Proje kimliği.
  • NUM_ADJ_INTERVALS: Sıfırdan ona kadar olan zaman aralığı aralıklarının sayısıdır. Varsayılan değer beştir.

    TOTP'ler, iki tarafın (kanıtlayıcı ve doğrulayıcı) aynı zaman aralığı içinde (genellikle 30 saniye uzunluğunda) OTP'leri oluşturduklarında aynı şifreyi oluşturmalarını sağlayarak çalışır. Bununla birlikte, taraflar arasındaki saat kaymasını ve gerçek kişilerin yanıt süresini hesaba katmak için TOTP hizmetini, bitişik pencerelerden gelen TOTP'leri de kabul edecek şekilde yapılandırabilirsiniz.

Bir kayıt kalıbı seçin

Uygulamanızın çok öğeli kimlik doğrulaması gerektirip gerektirmediğini, kullanıcılarınızı nasıl ve ne zaman kaydedeceğinizi seçebilirsiniz. Bazı yaygın kalıplar şunlardır:

  • Kullanıcının ikinci faktörünü kayıt işleminin bir parçası olarak kaydedin. Uygulamanız tüm kullanıcılar için çok öğeli kimlik doğrulaması gerektiriyorsa bu yöntemi kullanın.

  • Kayıt sırasında ikinci bir unsuru kaydetmek için atlanabilir bir seçenek sunmak. Uygulamanızda çok öğeli kimlik doğrulamasını teşvik etmek istiyor ancak zorunlu kılmak istemiyorsanız bu yaklaşımı kullanabilirsiniz.

  • Kayıt ekranı yerine kullanıcının hesabından veya profil yönetimi sayfasından ikinci bir faktör ekleme imkanı sağlayın. Bu sayede, kayıt sürecinde yaşanabilecek zorluklar en aza indirilirken güvenlik açısından hassas kullanıcılar için de çok öğeli kimlik doğrulaması kullanıma hazır olur.

  • Kullanıcı artırılmış güvenlik gereksinimleri olan özelliklere erişmek istediğinde aşamalı olarak ikinci bir faktör eklemeyi zorunlu kılın.

Kullanıcıları TOTP MFA'ya kaydetme

Uygulamanız için ikinci faktör olarak TOTP MFA'yı etkinleştirdikten sonra, kullanıcıları TOTP MFA'ya kaydetmek için istemci tarafı mantığı uygulayın:

  1. Kullanıcının kimliğini yeniden doğrulayın.

  2. Kimliği doğrulanmış kullanıcı için bir TOTP gizli anahtarı oluşturun:

    // 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. Gizli anahtarı kullanıcıya gösterin ve bunu kullanıcının kimlik doğrulayıcı uygulamasına girmesini isteyin:

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

    Gizli anahtarı görüntülemenin yanı sıra, bunu cihazın varsayılan kimlik doğrulayıcı uygulamasına otomatik olarak eklemeyi deneyebilirsiniz. Bunu yapmak için Google Authenticator ile uyumlu bir anahtar URI'si oluşturun ve openInOTPApp(withQRCodeURL:) hizmetine iletin:

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

    Kullanıcı, sırrını kimlik doğrulayıcı uygulamasına ekledikten sonra uygulama TOTP'ler oluşturmaya başlar.

  4. Kullanıcıdan, kimlik doğrulayıcı uygulaması tarafından görüntülenen TOTP'yi yazmasını ve MFA kaydını tamamlamak için bunu kullanmasını isteyin:

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

İkinci faktörle kullanıcıların oturumunu açma

TOTP MFA ile kullanıcıların oturumunu açmak için aşağıdaki kodu kullanın:

  1. signIn(with...:)- yöntemlerinden birini, MFA kullanmıyormuş gibi (örneğin, signIn(withEmail:password:)) çağırın. Yöntem, secondFactorRequired koduyla hata verirse uygulamanızın MFA akışını başlatın.

    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. Uygulamanızın MFA akışı ilk olarak kullanıcıdan, kullanmak istediği ikinci faktörü seçmesini istemelidir. MultiFactorResolver örneğinin hints özelliğini inceleyerek desteklenen ikinci faktörlerin listesini edinebilirsiniz:

    let mfaKey = AuthErrorUserInfoMultiFactorResolverKey
    guard let resolver = error.userInfo[mfaKey] as? MultiFactorResolver else { return }
    let enrolledFactors = resolver.hints.map(\.displayName)
    
  3. Kullanıcı TOTP kullanmayı tercih ederse kimlik doğrulayıcı uygulamasında görüntülenen TOTP'yi yazmasını ve oturum açmak için kullanmasını isteyin:

    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
    }
    

TOTP MFA kaydını iptal et

Bu bölümde, bir kullanıcının TOTP MFA kaydını iptal etme işleminin nasıl yapılacağı açıklanmaktadır.

Bir kullanıcı birden fazla MFA seçeneğine kaydolmuşsa ve en son etkinleştirilen seçenekteki kaydını silerse auth/user-token-expired alır ve oturumu kapatılır. Kullanıcı tekrar oturum açmalı ve mevcut kimlik bilgilerini (örneğin, e-posta adresi ve şifre) doğrulamalıdır.

Kullanıcının kaydını iptal etmek, hatayı işlemek ve yeniden kimlik doğrulamayı tetiklemek için aşağıdaki kodu kullanın:

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

Sırada ne var?