Android'de Apple Kullanarak Kimlik Doğrulama

Kullanıcılarınızın, uçtan uca OAuth 2.0 oturum açma akışını gerçekleştirmek için Firebase SDK'sını kullanarak Apple kimliklerini kullanarak Firebase ile kimlik doğrulaması yapmasına izin verebilirsiniz.

Başlamadan önce

Kullanıcıların Apple kullanarak oturum açmasını sağlamak için önce Apple'ın geliştirici sitesinde Apple ile Oturum Aç'ı yapılandırın, ardından Apple'ı Firebase projeniz için oturum açma sağlayıcısı olarak etkinleştirin.

Apple Developer Programı'na katılın

Apple ile oturum açma özelliği yalnızca Apple Developer Program üyeleri tarafından yapılandırılabilir.

Apple ile oturum açmayı yapılandırın

Apple Developer sitesinde aşağıdakileri yapın:

  1. Web için Apple ile Oturum Açma'yı yapılandırma başlıklı makalenin ilk bölümünde açıklandığı şekilde web sitenizi uygulamanızla ilişkilendirin. İstendiğinde aşağıdaki URL'yi bir Dönüş URL'si olarak kaydedin:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Firebase proje kimliğinizi Firebase konsol ayarları sayfasından bulabilirsiniz.

    İşiniz bittiğinde, bir sonraki bölümde ihtiyaç duyacağınız yeni Hizmet Kimliğinizi not edin.

  2. Apple özel anahtarıyla oturum açma özelliğini oluşturun. Sonraki bölümde yeni özel anahtarınıza ve anahtar kimliğinize ihtiyacınız olacaktır.
  3. Firebase Authentication'ın kullanıcılara e-posta gönderen, e-posta bağlantısında oturum açma, e-posta adresi doğrulaması, hesap değişikliği iptali gibi özelliklerden herhangi birini kullanıyorsanız Apple özel e-posta geçiş hizmetini yapılandırın ve noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com (ya da özelleştirilmiş e-posta şablon alanınızı) kaydettirerek Apple'ın Firebase Authentication tarafından gönderilen e-postaları anonimleştirilmiş Apple e-posta adreslerine iletebilmesini sağlayın.

Apple'ı oturum açma sağlayıcısı olarak etkinleştir

  1. Firebase'i Android projenize ekleyin. Firebase konsolunda uygulamanızı oluştururken uygulamanızın SHA-1 imzasını kaydettiğinizden emin olun.
  2. Firebase konsolunda Auth bölümünü açın. Oturum açma yöntemi sekmesinde Apple sağlayıcısını etkinleştirin. Önceki bölümde oluşturduğunuz Hizmet Kimliğini belirtin. Ayrıca, OAuth kod akışı yapılandırma bölümünde, Apple Ekip Kimliğinizi ve bir önceki bölümde oluşturduğunuz özel anahtarı ve anahtar kimliğini belirtin.

Apple'ın anonimleştirilmiş veri şartlarına uyun

Apple ile Oturum Açma, kullanıcılara oturum açarken e-posta adresleri de dahil olmak üzere verilerini anonimleştirme seçeneği sunar. Bu seçeneği belirleyen kullanıcıların e-posta adresleri privaterelay.appleid.com alanında olur. Uygulamanızda Apple ile Oturum Açma özelliğini kullanırken bu anonimleştirilmiş Apple Kimlikleriyle ilgili geçerli tüm geliştirici politikalarına veya Apple şartlarına uymanız gerekir.

Buna, kişisel bilgileri doğrudan tanımlayan herhangi bir bilgiyi anonimleştirilmiş bir Apple kimliğiyle ilişkilendirmeden önce gerekli tüm kullanıcı izinlerini almak da dahildir. Firebase Authentication kullanılırken aşağıdaki işlemler dahil olabilir:

  • Bir e-posta adresini anonimleştirilmiş bir Apple kimliğine (veya tam tersi) bağlayın.
  • Telefon numarasını anonimleştirilmiş bir Apple kimliğine (veya tam tersi) bağlama
  • Anonim olmayan bir sosyal bilgiyi (Facebook, Google vb.) anonimleştirilmiş bir Apple kimliğine (veya tam tersi) bağlayın.

Yukarıdaki liste tam kapsamlı değildir. Uygulamanızın Apple'ın gereksinimlerini karşıladığından emin olmak için geliştirici hesabınızın Üyelik bölümündeki Apple Geliştirici Programı Lisans Sözleşmesi'ne bakın.

Oturum açma akışını Firebase SDK'sı ile yönetme

Android'de, Apple hesaplarını kullanarak Firebase ile kullanıcılarınızın kimliklerini doğrulamanın en kolay yolu, oturum açma akışının tamamını Firebase Android SDK ile yönetmektir.

Firebase Android SDK ile oturum açma akışını yönetmek için aşağıdaki adımları uygulayın:

  1. apple.com sağlayıcı kimliğiyle Builder'ı kullanarak bir OAuthProvider örneği oluşturun:

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    
  2. İsteğe bağlı: Kimlik doğrulama sağlayıcısından istemek istediğiniz varsayılanın ötesinde ek OAuth 2.0 kapsamları belirtin.

    Kotlin+KTX

    provider.setScopes(arrayOf("email", "name"))
    

    Java

    List<String> scopes =
        new ArrayList<String>() {
          {
            add("email");
            add("name");
          }
        };
    provider.setScopes(scopes);
    

    Varsayılan olarak, E-posta adresi başına bir hesap etkinleştirildiğinde Firebase, e-posta ve ad kapsamları ister. Bu ayarı E-posta adresi başına birden çok hesap olarak değiştirirseniz Firebase, siz belirtmediğiniz sürece Apple'dan kapsam istemez.

  3. İsteğe bağlı: Apple'ın oturum açma ekranını İngilizce dışında bir dilde görüntülemek istiyorsanız locale parametresini ayarlayın. Desteklenen yerel ayarlar için Apple ile oturum açma dokümanlarına göz atın.

    Kotlin+KTX

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr")
    

    Java

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    
  4. OAuth sağlayıcı nesnesini kullanarak Firebase ile kimlik doğrulayın. Diğer FirebaseAuth işlemlerinden farklı olarak bu işlemin bir Özel Chrome Sekmesi açarak kullanıcı arayüzünüzün kontrolünü ele alacağını unutmayın. Bu nedenle, işlem kullanıcı arayüzünü başlattığında bunlar hemen ayrılacağı için eklediğiniz OnSuccessListener ve OnFailureListener içinde Etkinliğinize referans vermeyin.

    Öncelikle yanıt alıp almadığınızı kontrol etmeniz gerekir. Bu yöntemle oturum açtığınızda Etkinliğiniz arka plana alınır, bu da oturum açma akışı sırasında sistem tarafından geri çekilebileceği anlamına gelir. Böyle bir durumda kullanıcıyı tekrar denemek zorunda bırakmamak için zaten bir sonuç olup olmadığını kontrol etmelisiniz.

    Bekleyen bir sonuç olup olmadığını kontrol etmek için getPendingAuthResult() numaralı telefonu arayın:

    Kotlin+KTX

    val pending = auth.pendingAuthResult
    if (pending != null) {
        pending.addOnSuccessListener { authResult ->
            Log.d(TAG, "checkPending:onSuccess:$authResult")
            // Get the user profile with authResult.getUser() and
            // authResult.getAdditionalUserInfo(), and the ID
            // token from Apple with authResult.getCredential().
        }.addOnFailureListener { e ->
            Log.w(TAG, "checkPending:onFailure", e)
        }
    } else {
        Log.d(TAG, "pending: null")
    }
    

    Java

    mAuth = FirebaseAuth.getInstance();
    Task<AuthResult> pending = mAuth.getPendingAuthResult();
    if (pending != null) {
        pending.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                Log.d(TAG, "checkPending:onSuccess:" + authResult);
                // Get the user profile with authResult.getUser() and
                // authResult.getAdditionalUserInfo(), and the ID
                // token from Apple with authResult.getCredential().
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "checkPending:onFailure", e);
            }
        });
    } else {
        Log.d(TAG, "pending: null");
    }
    

    Bekleyen sonuç yoksa startActivityForSignInWithProvider() çağrısı yaparak oturum açma akışını başlatın:

    Kotlin+KTX

    auth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener { authResult ->
                // Sign-in successful!
                Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}")
                val user = authResult.user
                // ...
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "activitySignIn:onFailure", e)
            }
    

    Java

    mAuth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Sign-in successful!
                            Log.d(TAG, "activitySignIn:onSuccess:" + authResult.getUser());
                            FirebaseUser user = authResult.getUser();
                            // ...
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.w(TAG, "activitySignIn:onFailure", e);
                        }
                    });
    

    Firebase Auth tarafından desteklenen diğer sağlayıcıların aksine, Apple bir fotoğraf URL'si sağlamaz.

    Ayrıca, kullanıcı, e-postasını uygulamayla paylaşmamayı seçtiğinde Apple bu kullanıcı için benzersiz bir e-posta adresi sağlar (xyz@privaterelay.appleid.com biçiminde) ve bu adres uygulamanızla paylaşılır. Özel e-posta geçiş hizmetini yapılandırdıysanız Apple anonimleştirilmiş adrese gönderilen e-postaları kullanıcının gerçek e-posta adresine yönlendirir.

    Apple, görünen ad gibi kullanıcı bilgilerini yalnızca bir kullanıcı ilk kez oturum açtığında uygulamalarla paylaşır. Genellikle Firebase, kullanıcı Apple'da ilk oturum açtığında görünen adı depolar. Bu ada getCurrentUser().getDisplayName() ile ulaşabilirsiniz. Ancak, daha önce Firebase kullanmadan uygulamada bir kullanıcının oturumunu açmak için Apple'ı kullandıysanız Apple, Firebase'e kullanıcının görünen adını sağlamaz.

Yeniden kimlik doğrulama ve hesap bağlama

Aynı kalıp, son oturum açma gerektiren hassas işlemler için yeni bir kimlik bilgisi almak üzere kullanabileceğiniz startActivityForReauthenticateWithProvider() ile de kullanılabilir:

Kotlin+KTX

// The user is already signed-in.
val firebaseUser = auth.getCurrentUser()

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener( authResult -> {
        // User is re-authenticated with fresh tokens and
        // should be able to perform sensitive operations
        // like account deletion and email or password
        // update.
    })
    .addOnFailureListener( e -> {
        // Handle failure.
    })

Java

// The user is already signed-in.
FirebaseUser firebaseUser = mAuth.getCurrentUser();

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener(
        new OnSuccessListener<AuthResult>() {
          @Override
          public void onSuccess(AuthResult authResult) {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
          }
        })
    .addOnFailureListener(
        new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Handle failure.
          }
        });

Ayrıca, farklı kimlik sağlayıcıları mevcut hesaplara bağlamak için linkWithCredential() kullanabilirsiniz.

Apple hesaplarını diğer verilere bağlamadan önce, Apple'ın kullanıcılardan açık izin almanızı zorunlu tuttuğunu unutmayın.

Örneğin, bir Facebook hesabını geçerli Firebase hesabına bağlamak için kullanıcının Facebook'ta oturum açmasını sağlayarak aldığınız erişim jetonunu kullanın:

Kotlin+KTX

// Initialize a Facebook credential with a Facebook access token.
val credential = FacebookAuthProvider.getCredential(token.getToken())

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, task -> {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      });

Java

// Initialize a Facebook credential with a Facebook access token.
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      }
    });

Gelişmiş: Oturum açma akışını manuel olarak yönetme

Firebase ile kimlik doğrulamak için Apple Sign-In JS SDK'sını, Apple Sign-In JS SDK'sını kullanarak, OAuth akışını manuel olarak oluşturarak veya AppAuth gibi bir OAuth kitaplığı kullanarak oturum açma akışını yöneterek Apple Hesabı üzerinden de Firebase ile kimlik doğrulaması yapabilirsiniz.

  1. Her oturum açma isteği için, aldığınız kimlik jetonunun, uygulamanızın kimlik doğrulama isteğine özel olarak verildiğinden emin olmak amacıyla kullanacağınız rastgele bir dize ("tek seferlik") oluşturun. Bu adım, tekrar oynatma saldırılarını önlemek için önemlidir.

    Aşağıdaki örnekte olduğu gibi, Android'de SecureRandom ile kriptografik olarak güvenli bir tek seferlik rastgele sayı oluşturabilirsiniz:

    Kotlin+KTX

    private fun generateNonce(length: Int): String {
        val generator = SecureRandom()
    
        val charsetDecoder = StandardCharsets.US_ASCII.newDecoder()
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE)
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE)
    
        val bytes = ByteArray(length)
        val inBuffer = ByteBuffer.wrap(bytes)
        val outBuffer = CharBuffer.allocate(length)
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes)
            inBuffer.rewind()
            charsetDecoder.reset()
            charsetDecoder.decode(inBuffer, outBuffer, false)
        }
        outBuffer.flip()
        return outBuffer.toString()
    }
    

    Java

    private String generateNonce(int length) {
        SecureRandom generator = new SecureRandom();
    
        CharsetDecoder charsetDecoder = StandardCharsets.US_ASCII.newDecoder();
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE);
    
        byte[] bytes = new byte[length];
        ByteBuffer inBuffer = ByteBuffer.wrap(bytes);
        CharBuffer outBuffer = CharBuffer.allocate(length);
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes);
            inBuffer.rewind();
            charsetDecoder.reset();
            charsetDecoder.decode(inBuffer, outBuffer, false);
        }
        outBuffer.flip();
        return outBuffer.toString();
    }
    

    Ardından, nonce'un SHA246 karmasını onaltılık dize olarak alın:

    Kotlin+KTX

    private fun sha256(s: String): String {
        val md = MessageDigest.getInstance("SHA-256")
        val digest = md.digest(s.toByteArray())
        val hash = StringBuilder()
        for (c in digest) {
            hash.append(String.format("%02x", c))
        }
        return hash.toString()
    }
    

    Java

    private String sha256(String s) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(s.getBytes());
        StringBuilder hash = new StringBuilder();
        for (byte c: digest) {
            hash.append(String.format("%02x", c));
        }
        return hash.toString();
    }
    

    Oturum açma isteğinizle birlikte tek seferlik rastgele sayının SHA256 karmasını gönderirsiniz. Apple, yanıtta bunu değiştirmez. Firebase, orijinal tek seferlik rastgele sayıya karma oluşturma işlemi uygulayıp bunu Apple tarafından iletilen değerle karşılaştırarak yanıtı doğrular.

  2. OAuth kitaplığınızı veya başka bir yöntemi kullanarak Apple'ın oturum açma akışını başlatın. Karma oluşturma işlemi uygulanmış tek seferlik rastgele sayıyı isteğinize parametre olarak eklediğinizden emin olun.

  3. Apple'ın yanıtını aldıktan sonra yanıttan kimlik jetonunu alın ve bu jetonla birlikte karma oluşturma işlemi uygulanmamış tek seferlik rastgele değeri kullanarak bir AuthCredential oluşturun:

    Kotlin+KTX

    val credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build()
    

    Java

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    
  4. Firebase kimlik bilgisini kullanarak Firebase ile kimlik doğrulayın:

    Kotlin+KTX

    auth.signInWithCredential(credential)
          .addOnCompleteListener(this) { task ->
              if (task.isSuccessful) {
                // User successfully signed in with Apple ID token.
                // ...
              }
          }
    

    Java

    mAuth.signInWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
          @Override
          public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
              // User successfully signed in with Apple ID token.
              // ...
            }
          }
        });
    

signInWithCredential çağrısı başarılı olursa kullanıcının hesap verilerini almak için getCurrentUser yöntemini kullanabilirsiniz.

Jeton İptali

Apple, App Store İnceleme Yönergeleri'nde açıklandığı gibi, hesap oluşturma özelliğini destekleyen uygulamaların kullanıcılara uygulama içinde hesaplarını silme izni vermelerini zorunlu kılar

Ayrıca, Apple ile oturum açma özelliğini destekleyen uygulamalar kullanıcı jetonlarını iptal etmek için Apple ile oturum açma REST API'sini kullanmalıdır.

Bu koşulu karşılamak için aşağıdaki adımları uygulayın:

  1. Apple'ı kullanarak oturum açmak ve AuthResult edinmek için startActivityForSignInWithProvider() yöntemini kullanın.

  2. Apple sağlayıcısı için erişim jetonunu alın.

    Kotlin+KTX

    val oauthCredential: OAuthCredential =  authResult.credential
    val accessToken = oauthCredential.accessToken
    

    Java

    OAuthCredential oauthCredential = (OAuthCredential) authResult.getCredential();
    String accessToken = oauthCredential.getAccessToken();
    
  3. revokeAccessToken API'sini kullanarak jetonu iptal edin.

    Kotlin+KTX

    mAuth.revokeAccessToken(accessToken)
      .addOnCompleteListener(this) { task ->
        if (task.isSuccessful) {
          // Access token successfully revoked
          // for the user ...
        }
    }
    

    Java

    mAuth.revokeAccessToken(accessToken)
        .addOnCompleteListener(this, new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
              if (task.isSuccessful()) {
                // Access token successfully revoked
                // for the user ...
              }
            }
      });
    
  1. Son olarak, kullanıcı hesabını (ve tüm ilişkili verileri) silin

    Sonraki adımlar

    Bir kullanıcı ilk kez oturum açtığında yeni bir kullanıcı hesabı oluşturulur ve oturum açan kullanıcının kimlik bilgilerine (kullanıcı adı, ş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ığına bakılmaksızın projenizdeki her uygulamada bir 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önetme başlıklı makaleyi inceleyin.

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

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

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

    Kotlin+KTX

    Firebase.auth.signOut()

    Java

    FirebaseAuth.getInstance().signOut();