Kullanıcılarınızın Apple kimliklerini kullanarak Firebase ile kimlik doğrulaması yapmasını sağlamak için uçtan uca OAuth 2.0 oturum açma akışını gerçekleştirmek için Firebase SDK'sını kullanın.
Başlamadan önce
Apple kullanarak kullanıcıların oturumunu açmak için önce Apple ile oturum açma özelliğini yapılandırın Apple'ın geliştirici sitesinde Apple'ı oturum açma sağlayıcısı olarak etkinleştirin Firebase projesi.
Apple Developer Program'a katılın
Apple ile Oturum Açma özelliği, yalnızca Apple Developer'ın üyeleri tarafından yapılandırılabilir Program'ı tıklayın.
Apple ile oturum açma özelliğini yapılandırın
- Şuradaki uygulamanız için Apple ile Oturum Açma'yı etkinleştirin: Sertifikalar, Tanımlayıcılar ve Profiller sayfasındaki talimatları uygulayın.
- Web sitenizi, ilk bölümde açıklandığı şekilde uygulamanızla ilişkilendirin.
Web için Apple ile Oturum Açma'yı yapılandırma başlıklı makaleye göz atın. İstendiğinde
Dönüş URL'si olarak şu URL:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
. Firebase proje kimliğinizi Firebase konsol ayarları sayfasında bulabilirsiniz. İşiniz bittiğinde yeni Hizmet Kimliğinizi not edin. Bu belgeyi ele alacağız. - Oluştur: Apple özel anahtarıyla oturum açma başlıklı makaleyi inceleyin. Yeni özel anahtarınıza ve anahtarınıza ihtiyacınız olacak kimliğini girin.
- Firebase Authentication ürününün kullanıcılara e-posta gönderen özelliklerinden herhangi birini kullanıyorsanız
e-posta bağlantısı oturum açma, e-posta adresi doğrulama, hesap değişikliği dahil
iptal ve
Apple özel e-posta geçiş hizmetini yapılandırın
ve kaydolun
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com
(veya özelleştirilmiş e-posta şablon alanınızı) kullanın. Böylece Apple, gönderilen e-postaları aktarabilir Firebase Authentication tarafından anonimleştirilmiş Apple e-posta adreslerine gönderildi.
Apple'ı oturum açma sağlayıcısı olarak etkinleştir
- Firebase'i Apple projenize ekleyin. Şunları yaptığınızdan emin olun: uygulamanızı Firebase konsolu.
- 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 kodu akışı yapılandırma bölümü, Apple Ekip Kimliğinizi ve Önceki bölümde oluşturduğunuz özel anahtar ve anahtar kimliği.
Apple'ın anonimleştirilmiş veri şartlarına uyma
Apple ile Oturum Açma, kullanıcılara verilerini anonimleştirme seçeneği sunar.
oturum açarken kullandıkları e-posta adresleri de dahil. Bu seçeneği belirleyen kullanıcılar
privaterelay.appleid.com
alan adına sahip e-posta adresleri var. Zaman
Uygulamanızda Apple ile Oturum Açma özelliğini kullanıyorsanız geçerli tüm
bu anonimleştirilmiş Apple ile ilgili geliştirici politikaları veya Apple'ın şartları
Kimlikler.
Buna, hesabınızı kullanmadan önce gerekli kullanıcı rızasının alınması da dahildir. doğrudan tanımlayıcı kişisel bilgileri anonimleştirilmiş bir Apple ile ilişkilendirme Kimlik. Firebase Authentication kullanılırken şunlar dahil olabilir: işlemler:
- Bir e-posta adresini anonimleştirilmiş 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 kimliği (ör. Facebook, Google) veya tam tersi de geçerlidir.
Yukarıdaki listede olası her duruma yer verilmemiştir. Apple Developer Program'ı inceleyin Geliştirici hesabınızın Üyelik bölümündeki Lisans Sözleşmesi'ni Uygulamanızın Apple'ın gereksinimlerini karşıladığından emin olun.
Apple ile oturum açma ve Firebase ile kimlik doğrulama
Bir Apple hesabıyla kimlik doğrulamak için önce kullanıcının Apple'da oturum açmasını sağlayın
Apple'ın AuthenticationServices
çerçevesini kullanan hesap
ve ardından Firebase'i oluşturmak için Apple'ın yanıtındaki kimlik jetonunu kullanın.
AuthCredential
nesne:
Her oturum açma isteği için rastgele bir dize oluşturun. "nonce": Aldığınız kimlik jetonunun şu olduğundan emin olmak için kullanırsınız: özel olarak uygulamanızın kimlik doğrulama isteğine yanıt olarak verilir. Bu adımı, tekrar saldırılarını önlemek için önemlidir.
Tek başına güvenli tek seferlik rastgele sayı oluşturmak için
SecRandomCopyBytes(_:_:_)
, aşağıdaki örnekte gösterildiği gibi:Swift
private func randomNonceString(length: Int = 32) -> String { precondition(length > 0) var randomBytes = [UInt8](repeating: 0, count: length) let errorCode = SecRandomCopyBytes(kSecRandomDefault, randomBytes.count, &randomBytes) if errorCode != errSecSuccess { fatalError( "Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)" ) } let charset: [Character] = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._") let nonce = randomBytes.map { byte in // Pick a random character from the set, wrapping around if needed. charset[Int(byte) % charset.count] } return String(nonce) }
Objective-C
// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce - (NSString *)randomNonce:(NSInteger)length { NSAssert(length > 0, @"Expected nonce to have positive length"); NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; NSMutableString *result = [NSMutableString string]; NSInteger remainingLength = length; while (remainingLength > 0) { NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16]; for (NSInteger i = 0; i < 16; i++) { uint8_t random = 0; int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random); NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode); [randoms addObject:@(random)]; } for (NSNumber *random in randoms) { if (remainingLength == 0) { break; } if (random.unsignedIntValue < characterSet.length) { unichar character = [characterSet characterAtIndex:random.unsignedIntValue]; [result appendFormat:@"%C", character]; remainingLength--; } } } return [result copy]; }
Oturum açma isteğinizle birlikte tek seferlik rastgele sayının SHA256 karmasını gönderirsiniz. Apple, hiçbir değişiklik yapmadan yanıtta geçer. Firebase yanıtı doğrular karma oluşturma işlemini uygulayarak orijinal tek seferlik rastgele sayının karma hale getirilmesi ve Apple tarafından iletilen değerle karşılaştırılması gerekir.
Swift
@available(iOS 13, *) private func sha256(_ input: String) -> String { let inputData = Data(input.utf8) let hashedData = SHA256.hash(data: inputData) let hashString = hashedData.compactMap { String(format: "%02x", $0) }.joined() return hashString }
Objective-C
- (NSString *)stringBySha256HashingString:(NSString *)input { const char *string = [input UTF8String]; unsigned char result[CC_SHA256_DIGEST_LENGTH]; CC_SHA256(string, (CC_LONG)strlen(string), result); NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { [hashed appendFormat:@"%02x", result[i]]; } return hashed; }
İsteğinizde Apple'ın yanıtını işleyecek tek seferlik rastgele sayısı ve temsilci sınıfı (bkz. sıradaki adıma geçin):
Swift
import CryptoKit // Unhashed nonce. fileprivate var currentNonce: String? @available(iOS 13, *) func startSignInWithAppleFlow() { let nonce = randomNonceString() currentNonce = nonce let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] request.nonce = sha256(nonce) let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests() }
Objective-C
@import CommonCrypto; - (void)startSignInWithAppleFlow { NSString *nonce = [self randomNonce:32]; self.currentNonce = nonce; ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init]; ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest]; request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail]; request.nonce = [self stringBySha256HashingString:nonce]; ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]]; authorizationController.delegate = self; authorizationController.presentationContextProvider = self; [authorizationController performRequests]; }
ASAuthorizationControllerDelegate
Oturum açma başarılı olduysa kimliği kullanın Apple'ın yanıtından gelen ve karma oluşturma işlemi uygulanmamış tek seferlik rastgele sayı içeren jetondan Firebase:Swift
@available(iOS 13.0, *) extension MainViewController: ASAuthorizationControllerDelegate { func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential { guard let nonce = currentNonce else { fatalError("Invalid state: A login callback was received, but no login request was sent.") } guard let appleIDToken = appleIDCredential.identityToken else { print("Unable to fetch identity token") return } guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else { print("Unable to serialize token string from data: \(appleIDToken.debugDescription)") return } // Initialize a Firebase credential, including the user's full name. let credential = OAuthProvider.appleCredential(withIDToken: idTokenString, rawNonce: nonce, fullName: appleIDCredential.fullName) // Sign in with Firebase. Auth.auth().signIn(with: credential) { (authResult, error) in if error { // Error. If error.code == .MissingOrInvalidNonce, make sure // you're sending the SHA256-hashed nonce as a hex string with // your request to Apple. print(error.localizedDescription) return } // User is signed in to Firebase with Apple. // ... } } } func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // Handle error. print("Sign in with Apple errored: \(error)") } }
Objective-C
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) { if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential; NSString *rawNonce = self.currentNonce; NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent."); if (appleIDCredential.identityToken == nil) { NSLog(@"Unable to fetch identity token."); return; } NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding]; if (idToken == nil) { NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken); } // Initialize a Firebase credential, including the user's full name. FIROAuthCredential *credential = [FIROAuthProvider appleCredentialWithIDToken:IDToken rawNonce:self.appleRawNonce fullName:appleIDCredential.fullName]; // Sign in with Firebase. [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error != nil) { // Error. If error.code == FIRAuthErrorCodeMissingOrInvalidNonce, // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. return; } // Sign-in succeeded! }]; } } - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) { NSLog(@"Sign in with Apple errored: %@", error); }
Firebase Auth tarafından desteklenen diğer sağlayıcıların aksine, Apple fotoğraf URL'si.
Ayrıca kullanıcı, e-postalarını uygulamayla paylaşmamayı seçtiğinde Apple,
söz konusu kullanıcı için benzersiz bir e-posta adresi (
xyz@privaterelay.appleid.com
) çıkar ve bunları uygulamanızla paylaşır. Şu durumda:
özel e-posta geçiş hizmetini yapılandırdığında, Apple
kullanıcının gerçek e-posta adresine anonimleştirilmiş adres.
Yeniden kimlik doğrulama ve hesap bağlama
Aynı deseni reauthenticateWithCredential()
için de kullanabilirsiniz.
gereken hassas işlemler için yeni kimlik bilgileri almak üzere
son oturum açma işlemi:
Swift
// Initialize a fresh Apple credential with Firebase.
let credential = OAuthProvider.credential(
withProviderID: "apple.com",
IDToken: appleIdToken,
rawNonce: rawNonce
)
// Reauthenticate current Apple user with fresh Apple credential.
Auth.auth().currentUser.reauthenticate(with: credential) { (authResult, error) in
guard error != nil else { return }
// Apple user successfully re-authenticated.
// ...
}
Objective-C
FIRAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com",
IDToken:appleIdToken,
rawNonce:rawNonce];
[[FIRAuth auth].currentUser
reauthenticateWithCredential:credential
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error) {
// Handle error.
}
// Apple user successfully re-authenticated.
// ...
}];
Dilerseniz linkWithCredential()
kullanarak farklı kimlik sağlayıcıları da
hesaplar.
Apple, bağlantı oluşturmadan önce kullanıcılardan açıkça izin almanızı zorunlu kılar. diğer verilere aktarmalarını sağlar.
Apple ile oturum açmak, bir
mevcut hesabınızda oturum açın. Apple ile oturum açma kimlik bilgilerini başka bir kimlik bilgisine bağlamak istiyorsanız
hesabınıza erişmek için öncelikle eski şununla oturum açma yöntemini kullanarak hesapları bağlamayı denemeniz gerekir:
Apple kimlik bilgisi ve ardından yeni kimlik bilgisi bulmak için döndürülen hatayı inceleyin.
Yeni kimlik bilgisi hatanın userInfo
sözlüğünde bulunur ve
AuthErrorUserInfoUpdatedCredentialKey
tuşuyla erişilebilir.
Örneğin, bir Facebook hesabını mevcut Firebase hesabına bağlamak için kullanıcının Facebook'ta oturum açarak aldığınız erişim jetonu:
Swift
// Initialize a Facebook credential with Firebase.
let credential = FacebookAuthProvider.credential(
withAccessToken: AccessToken.current!.tokenString
)
// Assuming the current user is an Apple user linking a Facebook provider.
Auth.auth().currentUser.link(with: credential) { (authResult, error) in
// Facebook credential is linked to the current Apple user.
// The user can now sign in with Facebook or Apple to the same Firebase
// account.
// ...
}
Objective-C
// Initialize a Facebook credential with Firebase.
FacebookAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:accessToken];
// Assuming the current user is an Apple user linking a Facebook provider.
[FIRAuth.auth linkWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
// Facebook credential is linked to the current Apple user.
// The user can now sign in with Facebook or Apple to the same Firebase
// account.
// ...
}];
Jeton iptali
Apple, hesap oluşturma özelliğini destekleyen uygulamaların, kullanıcıların işlemi başlatmasına izin vermesini zorunlu kılar App Store İncelemesi'nde açıklandığı gibi, uygulama içinde hesabının silinmesi Kurallar
Bu koşulu karşılamak için aşağıdaki adımları uygulayın:
Hizmet Kimliği ve OAuth kodu akış yapılandırmasını doldurduğunuzdan emin olun. bölümünde ( Apple ile oturum açma özelliğini yapılandırın.
Kullanıcılar şununla oluşturulmuşsa Firebase, kullanıcı jetonlarını depolamaz: Apple ile oturum açın. ve hesabı silmeniz gerekir.
Swift
private func deleteCurrentUser() { do { let nonce = try CryptoUtils.randomNonceString() currentNonce = nonce let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] request.nonce = CryptoUtils.sha256(nonce) let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests() } catch { // In the unlikely case that nonce generation fails, show error view. displayError(error) } }
ASAuthorizationAppleIDCredential
sitesinden yetkilendirme kodunu alın ve iptal etmek içinAuth.auth().revokeToken(withAuthorizationCode:)
işlevini çağırmak için kullanıcının jetonları.Swift
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else { print("Unable to retrieve AppleIDCredential") return } guard let _ = currentNonce else { fatalError("Invalid state: A login callback was received, but no login request was sent.") } guard let appleAuthCode = appleIDCredential.authorizationCode else { print("Unable to fetch authorization code") return } guard let authCodeString = String(data: appleAuthCode, encoding: .utf8) else { print("Unable to serialize auth code string from data: \(appleAuthCode.debugDescription)") return } Task { do { try await Auth.auth().revokeToken(withAuthorizationCode: authCodeString) try await user?.delete() self.updateUI() } catch { self.displayError(error) } } }
Son olarak, kullanıcı hesabını (ve ilişkili tüm verileri) silin
Sonraki adımlar
Kullanıcı ilk kez oturum açtığında yeni bir kullanıcı hesabı oluşturulur ve bilgileri (kullanıcı adı ve şifre, telefon numarası) Numara veya kimlik doğrulama sağlayıcı bilgileri (oturum açan kullanıcı). Bu yeni Firebase projenizin bir parçası olarak saklanır ve aşağıdaki verileri tanımlamak için kullanılabilir: nasıl oturum açarsa açsın, projenizdeki tüm uygulamalarda kullanılır.
-
Uygulamalarınızda, kullanıcıların temel profil bilgilerini şuradan alabilirsiniz:
User
nesnesini tanımlayın. Kullanıcıları Yönetme başlıklı makaleye göz atın. Firebase Realtime Database ve Cloud Storage içinde Güvenlik Kuralları'nı kullanarak şunları yapabilirsiniz:
auth
değişkeninden, oturum açmış kullanıcının benzersiz kullanıcı kimliğini alabilirsiniz. ve kullanıcının hangi verilere erişebileceğini kontrol etmek için kullanılır.
Kullanıcıların çoklu kimlik doğrulama kullanarak uygulamanızda oturum açmasına izin verebilirsiniz yetkilendirme sağlayıcısının kimlik bilgilerini hesaba katılmaz.
Bir kullanıcının oturumunu kapatmak için numaralı telefonu arayın
signOut:
değerleridir.
Swift
let firebaseAuth = Auth.auth() do { try firebaseAuth.signOut() } catch let signOutError as NSError { print("Error signing out: %@", signOutError) }
Objective-C
NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; if (!status) { NSLog(@"Error signing out: %@", signOutError); return; }
Ayrıca tüm kimlik doğrulama aralığı için hata işleme kodu da ekleyebilirsiniz. hatalar. Hataları İşleme bölümüne bakın.