Android 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 Android SDK'sını yükleyin.

    TOTP MFA, yalnızca Android SDK v22.1.0 ve sonraki sürümlerde 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.
    Firebase.auth.currentUser.multiFactor.session
        .addOnSuccessListener { multiFactorSession ->
            TotpMultiFactorGenerator.generateSecret(multiFactorSession)
                .addOnSuccessListener { totpSecret ->
                    // 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:
    val 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() hizmetine iletin:

    val qrCodeUri = totpSecret.generateQrCodeUrl(
        currentUser.email ?: "default account",
        "Your App Name")
    totpSecret.openInOtpApp(qrCodeUri)
    

    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.
    val verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    val multiFactorAssertion = TotpMultiFactorGenerator
        .getAssertionForEnrollment(totpSecret, verificationCode)
    Firebase.auth.currentUser.multiFactor.enroll(multiFactorAssertion, "TOTP")
        .addOnSuccessListener {
            // Enrollment complete.
        }
    

İ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. signInWith- yöntemlerinden birini, MFA'yı kullanmıyormuş gibi çağırın. (Örneğin, signInWithEmailAndPassword().) Yöntem bir FirebaseAuthMultiFactorException döndürürse uygulamanızın MFA akışını başlatın.

    Firebase.auth.signInWithEmailAndPassword(email, password)
        .addOnSuccessListener { result ->
            // 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.)
    
            // ...
        }
        .addOnFailureListener { exception ->
            when (exception) {
                is FirebaseAuthMultiFactorException -> {
                    // Initiate your second factor sign-in flow. (See next step.)
                    // ...
                }
            }
        }
    
  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:

    val enrolledFactors = exception.resolver.hints.map { it.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:

    when (exception.resolver.hints[selectedIndex].factorId) {
        TotpMultiFactorGenerator.FACTOR_ID -> {
            val otpFromAuthenticator = // OTP typed by the user.
            val assertion = TotpMultiFactorGenerator.getAssertionForSignIn(
                exception.resolver.hints[selectedIndex].uid,
                otpFromAuthenticator
            )
            exception.resolver.resolveSignIn(assertion)
                .addOnSuccessListener { result ->
                    // Successfully signed in!
                }
                .addOnFailureListener { resolveError ->
                    // Invalid or expired OTP.
                }
        }
        PhoneMultiFactorGenerator.FACTOR_ID -> {
            // Handle SMS second factor.
        }
    }
    

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:

Firebase.auth.currentUser.multiFactor.unenroll(mfaEnrollmentId)
    .addOnSuccessListener {
        // Second factor unenrolled.
    }
    .addOnFailureListener { exception ->
        when (exception) {
            is FirebaseAuthInvalidUserException -> {
                // Second factor unenrolled. If the user was signed out, re-authenticate
                // them.

                // For example, if they signed in with a password, prompt them to
                // provide it again, then call `reauthenticateWithCredential()` as shown
                // below.
                val credential = EmailAuthProvider.getCredential(email, password)
                currentUser.reauthenticate(credential)
                    .addOnSuccessListener { 
                        // Success!
                    }
                    .addOnFailureListener { 
                        // Bad email address and password combination.
                    }
            }
        }
    }

Sırada ne var?