Android'de E-posta Bağlantısı'nı Kullanarak Firebase ile Kimlik Doğrulama

Firebase Authentication'i kullanarak kullanıcılara oturum açmaları için tıklayabilecekleri bir bağlantı içeren bir e-posta gönderebilirsiniz. Bu süreçte kullanıcının e-posta adresi de doğrulanır.

E-posta ile oturum açmanın birçok avantajı vardır:

  • Kolay kayıt ve oturum açma.
  • Uygulamalar arasında şifrelerin yeniden kullanılması riskini azaltır. Bu risk, iyi seçilmiş şifrelerin güvenliğini bile tehlikeye atabilir.
  • Bir kullanıcının kimliğini doğrularken aynı zamanda e-posta adresinin meşru sahibi olduğunu doğrulama olanağı.
  • Kullanıcıların oturum açmak için erişilebilir bir e-posta hesabına sahip olması yeterlidir. Telefon numarası veya sosyal medya hesabına sahip olmanız gerekmez.
  • Kullanıcı, mobil cihazlarda zahmetli olabilecek şifre sağlamadan (veya hatırlamadan) güvenli bir şekilde oturum açabilir.
  • Daha önce e-posta tanımlayıcısı (şifre veya birleşik) ile oturum açmış mevcut bir kullanıcının oturum açma yöntemi, yalnızca e-posta ile oturum açacak şekilde yükseltilebilir. Örneğin, şifresini unutmuş bir kullanıcı, şifresini sıfırlamak zorunda kalmadan oturum açabilir.

Başlamadan önce

Android projenizi oluşturma

  1. Henüz yapmadıysanız Firebase'i Android projenize ekleyin.

  2. Modül (uygulama düzeyi) Gradle dosyanıza (genellikle <project>/<app-module>/build.gradle.kts veya <project>/<app-module>/build.gradle) Android için Firebase Authentication kitaplığının bağımlılığını ekleyin. Kitaplık sürümlendirmesini kontrol etmek için Firebase Android BoM simgesini kullanmanızı öneririz.

    Ayrıca, Firebase Authentication'ü ayarlama kapsamında Google Play Hizmetleri SDK'sını uygulamanıza eklemeniz gerekir.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0")
    }

    Firebase Android BoM kullanıldığında uygulamanız Firebase Android kitaplıklarının daima uyumlu sürümlerini kullanır.

    (Alternatif) BoM

    Firebase BoM kullanmamayı seçerseniz her Firebase kitaplık sürümünü bağımlılık satırında belirtmeniz gerekir.

    Uygulamanızda birden fazla Firebase kitaplığı kullanıyorsanız kitaplık sürümlerini yönetmek için BoM'ı kullanmanızı önemle tavsiye ederiz. Bu, tüm sürümlerin uyumlu olmasını sağlar.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation("com.google.firebase:firebase-auth:23.1.0")
    // Also add the dependency for the Google Play services library and specify its version implementation("com.google.android.gms:play-services-auth:21.3.0")
    }
    Kotlin'e özgü bir kitaplık modülü mü arıyorsunuz? Ekim 2023'ten (Firebase BoM 32.5.0) itibaren hem Kotlin hem de Java geliştiricileri ana kitaplık modülünden yararlanabilir (ayrıntılar için bu girişimle ilgili SSS bölümüne bakın).

Kullanıcıların e-posta bağlantısıyla oturum açması için önce Firebase projeniz için e-posta sağlayıcıyı ve e-posta bağlantısı oturum açma yöntemini etkinleştirmeniz gerekir:

  1. Firebase konsolunda Auth bölümünü açın.
  2. Oturum açma yöntemi sekmesinde E-posta/Şifre sağlayıcısını etkinleştirin. E-posta bağlantısıyla oturum açma özelliğini kullanabilmek için e-posta/şifre ile oturum açma özelliğinin etkinleştirilmiş olması gerekir.
  3. Aynı bölümde, E-posta bağlantısı (şifresiz oturum açma) oturum açma yöntemini etkinleştirin.
  4. Kaydet'i tıklayın.

Kimlik doğrulama akışını başlatmak için kullanıcıya e-posta adresini girmesini isteyen bir arayüz gösterin ve ardından sendSignInLinkToEmail işlevini çağırarak Firebase'ın kimlik doğrulama bağlantısını kullanıcının e-postasına göndermesini isteyin.

  1. Firebase'e e-posta bağlantısının nasıl oluşturulacağına dair talimatlar sağlayan ActionCodeSettings nesnesini oluşturun. Aşağıdaki alanları ayarlayın:

    • url: Yerleştirilecek derin bağlantı ve iletilecek ek durum. Bağlantının alanının, Oturum açma yöntemi sekmesine (Kimlik doğrulama -> Oturum açma yöntemi) giderek bulabileceğiniz Firebase Console'daki yetkili alanlar listesinde beyaz listeye eklenmiş olması gerekir. Uygulama cihazında yüklü değilse ve yüklenemediyse bağlantı, kullanıcıyı bu URL'ye yönlendirir.
    • androidPackageName ve IOSBundleId: Oturum açma bağlantısı bir Android veya Apple cihazda açıldığında kullanılacak uygulamalar. E-posta işleme bağlantılarını mobil uygulamalar üzerinden açmak için Firebase Dynamic Links'ı yapılandırma hakkında daha fazla bilgi edinin.
    • handleCodeInApp: Doğru olarak ayarlanır. Diğer bant dışı e-posta işlemlerinden (şifre sıfırlama ve e-posta doğrulamaları) farklı olarak, oturum açma işleminin her zaman uygulamada tamamlanması gerekir. Bunun nedeni, akışın sonunda kullanıcının oturum açmış olması ve kimlik doğrulama durumunun uygulamada devam etmesidir.
    • dynamicLinkDomain: Bir proje için birden fazla özel dinamik bağlantı alanı tanımlandığında, bağlantı belirli bir mobil uygulama (örneğin, example.page.link) üzerinden açıldığında hangi alanın kullanılacağını belirtin. Aksi takdirde ilk alan otomatik olarak seçilir.

    Kotlin

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
            "com.example.android",
            true, // installIfNotAvailable
            "12", // minimumVersion
        )
    }

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    ActionCodeSettings hakkında daha fazla bilgi edinmek için E-posta İşlemlerinde Durumu İle İlgili Bilgileri Aktarma bölümüne bakın.

  2. Kullanıcıdan e-posta adresini isteyin.

  3. Kimlik doğrulama bağlantısını kullanıcının e-posta adresine gönderin ve kullanıcının e-posta ile oturum açma işlemini aynı cihazda tamamlaması ihtimaline karşı kullanıcının e-posta adresini kaydedin.

    Kotlin

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Email sent.")
            }
        }

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

Güvenlikle ilgili sorunlar

Bir oturum açma bağlantısının, istenmeyen bir kullanıcı olarak veya istenmeyen bir cihazda oturum açmak için kullanılmasını önlemek amacıyla Firebase Auth, oturum açma akışı tamamlanırken kullanıcının e-posta adresinin sağlanmasını zorunlu kılar. Oturum açmanın başarılı olması için bu e-posta adresinin, oturum açma bağlantısının orijinal olarak gönderildiği adresle eşleşmesi gerekir.

Oturum açma e-postasını gönderirken e-posta adreslerini yerel olarak depolayarak (ör. SharedPreferences'i kullanarak) oturum açma bağlantısını istenen cihazda açan kullanıcılar için bu akışı kolaylaştırabilirsiniz. Ardından, akışı tamamlamak için bu adresi kullanın. Kullanıcının e-posta adresini yönlendirme URL'si parametrelerine iletmeyin ve yeniden kullanmayın. Aksi takdirde oturum ekleme işlemleri etkinleştirilebilir.

Oturum açma işlemi tamamlandıktan sonra, daha önce doğrulanmamış oturum açma mekanizmaları kullanıcıdan kaldırılır ve mevcut oturumlar geçersiz kılınır. Örneğin, daha önce aynı e-posta ve şifreyle doğrulanmamış bir hesap oluşturan bir kullanıcının şifresi, sahiplik iddiasında bulunan ve doğrulanmamış hesabı oluşturan kimliğe bürünen kişinin doğrulanmamış e-posta ve şifreyle tekrar oturum açmasını önlemek için kaldırılır.

Ayrıca, bağlantınızın aracı sunucularca kesilmesi ihtimalini önlemek için üretimde HTTPS URL'si kullandığınızdan emin olun.

Android uygulamasında oturum açma işlemini tamamlama

Firebase Authentication, e-posta bağlantısını mobil cihaza göndermek için Firebase Dynamic Links'i kullanır. Mobil uygulama üzerinden oturum açmanın tamamlanması için uygulamanın, gelen uygulama bağlantısını algılayacak, temel derin bağlantıyı ayrıştıracak ve ardından oturumu tamamlayacak şekilde yapılandırılması gerekir.

Firebase Auth, mobil uygulamada açılması amaçlanan bir bağlantı gönderirken Firebase Dynamic Links'i kullanır. Bu özelliği kullanabilmek için Firebase konsolunda Dynamic Links'in yapılandırılmış olması gerekir.

  1. Firebase Dynamic Links'i etkinleştirin:

    1. Firebase konsolunda Dynamic Links bölümünü açın.
    2. Henüz Dynamic Links şartlarını kabul etmediyseniz ve Dynamic Links alanı oluşturmadıysanız şimdi yapın.

      Daha önce bir Dynamic Links alanı oluşturduysanız bunu not edin. Dynamic Links alanları genellikle aşağıdaki örnekteki gibi görünür:

      example.page.link

      Apple veya Android uygulamanızı gelen bağlantıyı kesecek şekilde yapılandırırken bu değere ihtiyacınız olacaktır.

  2. Android uygulamalarını yapılandırma:

    1. Android uygulamanızdan bu bağlantıları işleyebilmek için Android paket adının Firebase Console proje ayarlarında belirtilmesi gerekir. Ayrıca, uygulama sertifikasının SHA-1 ve SHA-256 değerlerinin de sağlanması gerekir.
    2. Dinamik bağlantı alanı eklediğinize ve Android uygulamanızın doğru şekilde yapılandırıldığından emin olduğunuza göre dinamik bağlantı, başlatıcı etkinliğinden başlayarak uygulamanıza yönlendirecektir.
    3. Dinamik bağlantının belirli bir etkinliğe yönlendirmesini istiyorsanız AndroidManifest.xml dosyanızda bir intent filtresi yapılandırmanız gerekir. Bu, intent filtresinde dinamik bağlantı alanınızı veya e-posta işlem işleyicisini belirterek yapılabilir. Varsayılan olarak e-posta işlem işleyicisi aşağıdaki örnekteki gibi bir alanda barındırılır:
      PROJECT_ID.firebaseapp.com/
    4. Uyarılar:
      1. Amaç filtrenizde actionCodeSettings'de ayarladığınız URL'yi belirtmeyin.
      2. Dinamik bağlantı alanınızı oluştururken kısa URL bağlantısı da oluşturmuş olabilirsiniz. Bu kısa URL iletilmez. Intent filtrenizi android:pathPrefix özelliğiyle yakalayacak şekilde yapılandırmayın. Bu, uygulamanızın farklı bölümlerinde farklı dinamik bağlantılar yakalayamayacağınız anlamına gelir. Ancak, hangi işlemin yapılmaya çalışıldığını görmek için bağlantıdaki mode sorgu parametresini kontrol edebilirsiniz veya uygulamanızın aldığı bağlantının istediğiniz işlemi yapıp yapmadığını görmek için isSignInWithEmailLink gibi SDK yöntemlerini kullanabilirsiniz.
    5. Dinamik bağlantılar alma hakkında daha fazla bilgi için Android Dinamik Bağlantıları alma talimatlarını inceleyin.

Yukarıda açıklandığı şekilde bağlantıyı aldıktan sonra, e-posta bağlantısı kimlik doğrulaması için tasarlandığını doğrulayın ve oturumu tamamlayın.

Kotlin

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully signed in with email link!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error signing in with email link", task.exception)
            }
        }
}

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

Apple uygulamalarında e-posta bağlantısıyla oturum açma özelliğini kullanma hakkında daha fazla bilgi edinmek için Apple platformları kılavuzuna bakın.

Web uygulamasında e-posta bağlantısıyla oturum açmayı nasıl yöneteceğiniz hakkında bilgi edinmek için Web kılavuzuna bakın.

Bu kimlik doğrulama yöntemini mevcut bir kullanıcıya da bağlayabilirsiniz. Örneğin, daha önce telefon numarası gibi başka bir sağlayıcıyla kimliğini doğrulayan bir kullanıcı, bu oturum açma yöntemini mevcut hesabına ekleyebilir.

Fark, işlemin ikinci yarısında ortaya çıkar:

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d(TAG, "Successfully linked emailLink credential!")
            val result = task.result
            // You can access the new user via result.getUser()
            // Additional user info profile *not* available via:
            // result.getAdditionalUserInfo().getProfile() == null
            // You can check if the user is new or existing:
            // result.getAdditionalUserInfo().isNewUser()
        } else {
            Log.e(TAG, "Error linking emailLink credential", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

Bu yöntem, hassas bir işlem yapmadan önce e-posta bağlantısı kullanıcısının kimliğini yeniden doğrulamak için de kullanılabilir.

Kotlin

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            // User is now successfully reauthenticated
        } else {
            Log.e(TAG, "Error reauthenticating", task.exception)
        }
    }

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

Ancak akış, orijinal kullanıcının oturum açmadığı farklı bir cihazda sona erebileceğinden bu akış tamamlanmayabilir. Bu durumda, kullanıcıya bağlantıyı aynı cihazda açmaya zorlamak için bir hata gösterilebilir. İşlemin türü ve kullanıcı kimliği hakkında bilgi sağlamak için bağlantıya bazı durum bilgileri iletilebilir.

Projenizi 15 Eylül 2023'te veya sonrasında oluşturduysanız e-posta numaralandırma koruması varsayılan olarak etkindir. Bu özellik, projenizin kullanıcı hesaplarının güvenliğini artırır ancak daha önce tanımlayıcı öncelikli akışları uygulamak için önerdiğimiz fetchSignInMethodsForEmail()yöntemini devre dışı bırakır.

Projeniz için e-posta numaralandırma korumasını devre dışı bırakabilirsiniz ancak bunu yapmamanızı öneririz.

Daha fazla ayrıntı için e-posta numaralandırma koruması ile ilgili dokümanları inceleyin.

Sonraki adımlar

Kullanıcı ilk kez oturum açtıktan sonra yeni bir kullanıcı hesabı oluşturulur ve kullanıcının oturum açarken kullandığı kimlik bilgilerine (yani kullanıcı adı ve şifre, telefon numarası veya kimlik doğrulama sağlayıcı bilgileri) bağlanır. Bu yeni hesap, Firebase projenizin bir parçası olarak depolanır ve kullanıcının nasıl oturum açtığından bağımsız olarak projenizdeki her uygulamada kullanıcıyı tanımlamak için kullanılabilir.

  • Uygulamalarınızda, kullanıcının temel profil bilgilerini FirebaseUser nesnesinden alabilirsiniz. Kullanıcıları Yönet başlıklı makaleyi inceleyin.

  • Firebase Realtime Database ve Cloud Storage Güvenlik Kurallarınızda, oturum açmış kullanıcının benzersiz kullanıcı kimliğini auth değişkeninden alabilir ve kullanıcının hangi verilere erişebileceğini kontrol etmek için kullanabilirsiniz.

Kimlik doğrulama sağlayıcı kimlik bilgilerini mevcut bir kullanıcı hesabına bağlayarak kullanıcıların uygulamanızda birden fazla kimlik doğrulama sağlayıcı kullanarak oturum açmasına izin verebilirsiniz.

Bir kullanıcının oturumunu kapatmak için signOut:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();