Uçtan uca OAuth 2.0 oturum açma akışını gerçekleştirmek için Firebase SDK'sını kullanarak kullanıcılarınızın Apple Kimliklerini kullanarak Firebase'de kimlik doğrulaması yapmasına izin verebilirsiniz.
Başlamadan önce
Kullanıcıların Apple ile oturum açmasını sağlamak için önce Apple'ın geliştirici sitesinde Apple ile Oturum Açma'yı yapılandırın, ardından Firebase projeniz için oturum açma sağlayıcı olarak Apple'ı etkinleştirin.
Apple Geliştirici Programı'na katılma
Apple ile oturum açma özelliği yalnızca Apple Developer Program üyeleri tarafından yapılandırılabilir.
Apple ile oturum açma özelliğini yapılandırma
Apple Developer sitesinde aşağıdakileri yapın:
-
Web için Apple ile oturum açma özelliğini 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 Dönüş URL'si olarak kaydedin:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
Firebase proje kimliğinizi Firebase konsol ayarları sayfasında bulabilirsiniz.
İşlemi tamamladığınızda yeni hizmet kimliğinizi not edin. Bu kimliğe bir sonraki bölümde ihtiyacınız olacak.
- Apple ile oturum açma özel anahtarı oluşturun. Bir sonraki bölümde yeni özel anahtarınız ve anahtar kimliğiniz gereklidir.
-
Kullanıcılara e-posta gönderen Firebase Authentication özelliklerinden herhangi birini kullanıyorsanız (ör. e-posta bağlantısıyla oturum açma, e-posta adresi doğrulama, hesap değişikliği iptali vb.), Apple'ın özel e-posta aktarma hizmetini yapılandırın ve
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com
(veya özelleştirilmiş e-posta şablonu alanınız) için kayıt yapın. Böylece Apple, Firebase Authentication tarafından gönderilen e-postaları anonimleştirilmiş Apple e-posta adreslerine aktarabilir.
Apple'ı oturum açma sağlayıcısı olarak etkinleştirme
- Firebase'i Android projenize ekleyin. Uygulamanızı Firebase konsolunda ayarlarken uygulamanızın SHA-1 imzasını kaydettiğinizden emin olun.
- Firebase konsolunda Auth (Kimlik Doğrulama) 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ırması bölümünde Apple Ekip Kimliğinizi ve önceki bölümde oluşturduğunuz özel anahtarı ve anahtar kimliğini belirtin.
Apple'ın anonimleştirilmiş veri şartlarına uyun
Apple ile Giriş, 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 privaterelay.appleid.com
alan adıyla e-posta adresleri olur. Uygulamanızda Apple ile Giriş'i kullandığınızda, bu anonimleştirilmiş Apple kimlikleriyle ilgili olarak Apple'ın geçerli tüm geliştirici politikalarına veya şartlarına uymanız gerekir.
Bu, kimliği doğrudan tanımlayan kişisel bilgileri anonimleştirilmiş bir Apple Kimliği ile ilişkilendirmeden önce gerekli kullanıcı iznini almayı içerir. Firebase Authentication kullanılırken aşağıdaki işlemler yapılabilir:
- Anonimleştirilmiş bir Apple Kimliği'ne e-posta adresi bağlayabilir veya tam tersini yapabilirsiniz.
- Anonimleştirilmiş bir Apple Kimliği'ne telefon numarası bağlama veya tam tersi
- Anonim olmayan bir sosyal kimlik bilgisini (Facebook, Google vb.) anonimleştirilmiş bir Apple Kimliği'ne veya tam tersi şekilde bağlamak
Yukarıdaki listede olası her duruma yer verilmemiştir. Uygulamanızın Apple'ın şartlarını 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.
Firebase SDK ile oturum açma akışını yönetme
Android'de, kullanıcılarınızın Apple hesaplarını kullanarak Firebase ile 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ı işlemek için aşağıdaki adımları uygulayın:
Sağlayıcı kimliği
apple.com
ile Builder'ını kullanarak birOAuthProvider
örneği oluşturun:Kotlin
val provider = OAuthProvider.newBuilder("apple.com")
Java
OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
İsteğe bağlı: Kimlik doğrulama sağlayıcısından istemek istediğiniz, varsayılanın ötesindeki ek OAuth 2.0 kapsamlarını belirtin.
Kotlin
provider.setScopes(arrayOf("email", "name"))
Java
List<String> scopes = new ArrayList<String>() { { add("email"); add("name"); } }; provider.setScopes(scopes);
E-posta adresi başına bir hesap ayarı varsayılan olarak etkinleştirildiğinde Firebase, e-posta ve ad kapsamları ister. Bu ayarı Bir e-posta adresi için birden fazla hesap olarak değiştirirseniz Firebase, siz belirtmediğiniz sürece Apple'dan kapsam isteğinde bulunmaz.
İsteğe bağlı: Apple'ın oturum açma ekranını İngilizce dışında bir dilde göstermek istiyorsanız
locale
parametresini ayarlayın. Desteklenen yerel ayarlar için Apple ile Giriş dokümanlarına bakın.Kotlin
// Localize the Apple authentication screen in French. provider.addCustomParameter("locale", "fr")
Java
// Localize the Apple authentication screen in French. provider.addCustomParameter("locale", "fr");
OAuth sağlayıcı nesnesini kullanarak Firebase ile kimlik doğrulayın. Diğer
FirebaseAuth
işlemlerinden farklı olarak bu işlemin, Özel Chrome Sekmesi açarak kullanıcı arayüzünüzü kontrol edeceğini unutmayın. Bu nedenle,OnSuccessListener
veOnFailureListener
'de Etkinliğinize referans vermeyin. Bunlar, işlem kullanıcı arayüzünü başlattığında hemen ayrılır.Ö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 nedenle, oturum açma akışı sırasında sistem tarafından geri alınabilir. Bu durum yaşandığında kullanıcının tekrar denemesini önlemek için sonucun zaten mevcut olup olmadığını kontrol etmeniz gerekir.
Bekleyen sonuç olup olmadığını kontrol etmek için
getPendingAuthResult()
numaralı telefonu arayın:Kotlin
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 bir sonuç yoksa
startActivityForSignInWithProvider()
numaralı telefonu arayarak oturum açma akışını başlatın:Kotlin
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, 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 (
xyz@privaterelay.appleid.com
biçiminde) sağlar ve bu adresi uygulamanızla paylaşı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, kullanıcı bilgilerini (ör. görünen ad) uygulamalarla yalnızca kullanıcı ilk kez oturum açtığında paylaşır. Firebase, genellikle kullanıcının Apple ile ilk kez oturum açtığında görünen adı depolar. Bu adı
getCurrentUser().getDisplayName()
ile alabilirsiniz. Ancak daha önce Firebase'i kullanmadan bir kullanıcının uygulamada oturum açması 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, startActivityForReauthenticateWithProvider()
ile de kullanılabilir. Bu kalıbı, son oturum açma işleminin gerekli olduğu hassas işlemler için yeni kimlik bilgisi almak üzere kullanabilirsiniz:
Kotlin
// 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'ın, kullanıcıların Apple hesaplarını diğer verilere bağlamadan önce kullanıcılardan açık rıza almanızı zorunlu kıldığını unutmayın.
Örneğin, bir Facebook hesabını mevcut Firebase hesabına bağlamak için kullanıcıyı Facebook'ta oturum açtığında aldığınız erişim jetonunu kullanın:
Kotlin
// 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
Oturum açma akışını Apple ile Oturum Açma JS SDK'sını kullanarak, OAuth akışını manuel olarak oluşturarak veya AppAuth gibi bir OAuth kitaplığı kullanarak yönetip Apple Hesabı ile Firebase'de kimlik doğrulaması da yapabilirsiniz.
Her oturum açma isteği için rastgele bir dize ("nonce") oluşturun. Bu dizeyi, aldığınız kimlik jetonunun özellikle uygulamanızın kimlik doğrulama isteğine yanıt olarak verildiğinden emin olmak için kullanırsınız. Bu adım, yeniden 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 kullanımlık sayı oluşturabilirsiniz:Kotlin
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'ın SHA256 karma değerini onaltılık dize olarak alın:
Kotlin
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 nonce'ın SHA256 hash değerini gönderirsiniz. Bu değer, Apple tarafından yanıtta değiştirilmeden iletilir. Firebase, orijinal nonce'ı karma oluşturma işlevinden geçirerek ve Apple tarafından iletilen değerle karşılaştırarak yanıtı doğrular.
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ış nonce'ı isteğinize parametre olarak eklediğinizden emin olun.
Apple'ın yanıtını aldıktan sonra, yanıttan kimlik jetonunu alın ve
AuthCredential
oluşturmak için bu jetonu ve karma oluşturulmamış nonce'u kullanın:Kotlin
val credential = OAuthProvider.newCredentialBuilder("apple.com") .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce) .build()
Java
AuthCredential credential = OAuthProvider.newCredentialBuilder("apple.com") .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce) .build();
Firebase kimlik bilgisiyle Firebase'de kimlik doğrulama:
Kotlin
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.
Jetonu İptal Etme
Apple, hesap oluşturmayı destekleyen uygulamaların, App Store İnceleme Kuralları'nda belirtildiği gibi kullanıcıların hesaplarını uygulama içinden silmelerine olanak tanımasını 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:
Apple ile oturum açmak ve
AuthResult
almak içinstartActivityForSignInWithProvider()
yöntemini kullanın.Apple sağlayıcısı için erişim jetonunu alın.
Kotlin
val oauthCredential: OAuthCredential = authResult.credential val accessToken = oauthCredential.accessToken
Java
OAuthCredential oauthCredential = (OAuthCredential) authResult.getCredential(); String accessToken = oauthCredential.getAccessToken();
revokeAccessToken
API'yi kullanarak jetonu iptal edin.Kotlin
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 ... } } });
- Son olarak, kullanıcı hesabını (ve ilişkili tüm verileri) silin.
Sonraki adımlar
Bir kullanıcı ilk kez oturum açtıktan sonra yeni bir kullanıcı hesabı oluşturulur ve kullanıcının oturum açtığı kimlik bilgilerine (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 oturum açma şeklinden 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önetme 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 bu kimliği 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
numaralı telefonu arayın:Kotlin
Firebase.auth.signOut()
Java
FirebaseAuth.getInstance().signOut();
-