Możesz umożliwić użytkownikom uwierzytelnianie się w Firebase za pomocą identyfikatora Apple, korzystając z pakietu Firebase SDK do przeprowadzenia pełnego procesu logowania OAuth 2.0.
Zanim zaczniesz
Aby umożliwić użytkownikom logowanie się za pomocą Apple, najpierw skonfiguruj logowanie przez Apple w witrynie dla deweloperów Apple, a potem włącz Apple jako dostawcę logowania w projekcie w Firebase.
Dołącz do programu Apple Developer Program
Logowanie przez Apple mogą skonfigurować tylko członkowie programu Apple Developer Program.
Skonfiguruj logowanie przez Apple
Logowanie przez Apple musi być włączone i prawidłowo skonfigurowane w projekcie w Firebase. Konfiguracja różni się w zależności od platformy Android i Apple. Zanim przejdziesz dalej, zapoznaj się z sekcją "Konfigurowanie logowania przez Apple" w przewodnikach dotyczących platform Apple lub Androida.Włącz Apple jako dostawcę logowania
- W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie.
- Na karcie Metoda logowania włącz dostawcę logowania Apple.
- Skonfiguruj ustawienia dostawcy logowania przez Apple:
- Apple: jeśli wdrażasz aplikację tylko na platformach Apple możesz pozostawić puste pola Identyfikator usługi, Identyfikator zespołu Apple, Klucz prywatny i Identyfikator klucza.
-
Android: aby obsługiwać urządzenia z Androidem, wykonaj te czynności:
- Dodaj Firebase do projektu aplikacji na Androida.
-
Jeśli jeszcze tego nie zrobisz, określ odcisk cyfrowy SHA-1 aplikacji.
-
W konsoli Firebase otwórz kartę
Ustawienia > Ogólne tab. - Przewiń w dół do karty Twoje aplikacje , wybierz aplikację na Androida i dodaj odcisk cyfrowy SHA-1 w polu Odciski cyfrowe certyfikatu SHA.
Więcej informacji o tym, jak uzyskać odcisk cyfrowy SHA aplikacji, znajdziesz w artykule Uwierzytelnianie klienta.
-
W konsoli Firebase otwórz kartę
-
Skonfiguruj ustawienia dostawcy logowania przez Apple:
- W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie.
- Na karcie Metoda logowania kliknij dostawcę logowania Apple.
- Określ identyfikator usługi utworzony w poprzedniej sekcji. W sekcji konfiguracji przepływu kodu OAuth określ też identyfikator zespołu Apple oraz klucz prywatny i identyfikator klucza utworzone w poprzedniej sekcji.
Spełnij wymagania Apple dotyczące anonimizacji danych
Logowanie przez Apple daje użytkownikom możliwość anonimizacji danych, w tym adresu e-mail, podczas logowania. Użytkownicy, którzy wybiorą tę opcję, będą mieli adresy e-mail z domeną privaterelay.appleid.com. Jeśli używasz logowania przez Apple w swojej aplikacji, musisz przestrzegać wszystkich obowiązujących zasad i warunków dla deweloperów Apple dotyczących tych anonimowych identyfikatorów Apple.
Obejmuje to uzyskanie wymaganej zgody użytkownika przed powiązaniem bezpośrednio identyfikujących danych osobowych z anonimowym identyfikatorem Apple. W przypadku korzystania z uwierzytelniania Firebase może to obejmować te działania:
- powiązanie adresu e-mail z anonimowym identyfikatorem Apple lub odwrotnie;
- powiązanie numeru telefonu z anonimowym identyfikatorem Apple lub odwrotnie;
- powiązanie nieanonimowych danych logowania w mediach społecznościowych (Facebook, Google itp.) z anonimowym identyfikatorem Apple lub odwrotnie.
Powyższa lista nie jest wyczerpująca. Aby mieć pewność, że Twoja aplikacja spełnia wymagania Apple, zapoznaj się z umową licencyjną programu Apple Developer Program w sekcji Członkostwo na koncie dewelopera.
Dostęp do zajęć firebase::auth::Auth
Klasa Auth jest bramą do wszystkich wywołań interfejsu API.
- Dodaj pliki nagłówkowe Auth i App:
#include "firebase/app.h" #include "firebase/auth.h"
- W kodzie inicjującym utwórz a
firebase::Appklasę.#if defined(__ANDROID__) firebase::App* app = firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity); #else firebase::App* app = firebase::App::Create(firebase::AppOptions()); #endif // defined(__ANDROID__)
- Pobierz zajęcia
firebase::auth::Authdlafirebase::App. Istnieje mapowanie 1:1 międzyAppaAuth.firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
Obsługa procesu logowania za pomocą pakietu Firebase SDK
Proces logowania przez Apple różni się w zależności od platformy Apple i Androida.
Na platformach Apple
Uwierzytelniaj użytkowników w Firebase za pomocą pakietu Apple Sign In Objective-C SDK wywoływanego z kodu C++.
W przypadku każdego żądania logowania wygeneruj losowy ciąg znaków – „nonce” – który będzie używany do sprawdzania, czy otrzymany token identyfikatora został przyznany specjalnie w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten krok jest ważny, aby zapobiec atakom typu replay.
- (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--; } } } }W żądaniu logowania wyślesz skrót SHA256 nonce, który Apple przekaże w odpowiedzi bez zmian. Firebase weryfikuje odpowiedź, obliczając skrót oryginalnego nonce i porównując go z wartością przekazaną przez Apple.
Uruchom proces logowania przez Apple, w tym w żądaniu skrót SHA256 liczby jednorazowej i klasę delegata, która będzie obsługiwać odpowiedź Apple (patrz następny krok):
- (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]; } - (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; }Obsłuż odpowiedź Apple w implementacji `ASAuthorizationControllerDelegate`. Jeśli logowanie się zakończyło się powodzeniem, użyj tokena identyfikatora z odpowiedzi Apple z niezaszyfrowanym nonce do uwierzytelnienia w Firebase:
- (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); } }Użyj wynikowego ciągu tokena i oryginalnej liczby jednorazowej, aby utworzyć dane logowania Firebase i zalogować się w Firebase.
firebase::auth::OAuthProvider::GetCredential( /*provider_id=*/"apple.com", token, nonce, /*access_token=*/nullptr); firebase::Future<firebase::auth::AuthResult> result = auth->SignInAndRetrieveDataWithCredential(credential);Tego samego wzorca można używać z
Reauthenticate, aby pobierać nowe dane logowania do operacji wrażliwych, które wymagają niedawnego logowania.firebase::Future<firebase::auth::AuthResult> result = user->Reauthenticate(credential);Tego samego wzorca można używać do łączenia konta z logowaniem przez Apple. Może jednak wystąpić błąd, gdy istniejące konto Firebase jest już połączone z kontem Apple, z którym próbujesz się połączyć. W takim przypadku przyszłość zwróci stan
kAuthErrorCredentialAlreadyInUse, aAuthResultmoże zawierać prawidłowecredential. Tych danych logowania można użyć do zalogowania się na połączone z Apple konto za pomocąSignInAndRetrieveDataWithCredentialbez konieczności generowania kolejnego tokena i liczby jednorazowej logowania przez Apple.firebase::Future<firebase::auth::AuthResult> link_result = auth->current_user().LinkWithCredential(credential); // To keep example simple, wait on the current thread until call completes. while (link_result.status() == firebase::kFutureStatusPending) { Wait(100); } // Determine the result of the link attempt if (link_result.error() == firebase::auth::kAuthErrorNone) { // user linked correctly. } else if (link_result.error() == firebase::auth::kAuthErrorCredentialAlreadyInUse && link_result.result() ->additional_user_info.updated_credential.is_valid()) { // Sign In with the new credential firebase::Future<firebase::auth::AuthResult> result = auth->SignInAndRetrieveDataWithCredential( link_result.result()->additional_user_info.updated_credential); } else { // Another link error occurred. }
W Androidzie
W Androidzie uwierzytelniaj użytkowników w Firebase, integrując ogólne logowanie OAuth w internecie z aplikacją za pomocą pakietu Firebase SDK, aby przeprowadzić pełny proces logowania.
Aby obsługiwać proces logowania za pomocą pakietu Firebase SDK, wykonaj te czynności:
Utwórz instancję
FederatedOAuthProviderDataskonfigurowaną z identyfikatorem dostawcy odpowiednim dla Apple.firebase::auth::FederatedOAuthProviderData provider_data("apple.com");Opcjonalnie: określ dodatkowe zakresy protokołu OAuth 2.0 poza domyślnymi, o które chcesz poprosić dostawcę uwierzytelniania.
provider_data.scopes.push_back("email"); provider_data.scopes.push_back("name");Opcjonalnie: jeśli chcesz wyświetlać ekran logowania Apple w innym języku niż angielski, ustaw parametr
locale. Obsługiwane ustawienia regionalne znajdziesz w dokumentacji logowania przez Apple.// Localize to French. provider_data.custom_parameters["language"] = "fr"; ```Gdy dane dostawcy zostaną skonfigurowane, użyj ich do utworzenia FederatedOAuthProvider.
// Construct a FederatedOAuthProvider for use in Auth methods. firebase::auth::FederatedOAuthProvider provider(provider_data);Uwierzytelnij się w Firebase za pomocą obiektu dostawcy Uwierzytelniania. Pamiętaj, że w przeciwieństwie do innych operacji FirebaseAuth ta operacja przejmie kontrolę nad interfejsem użytkownika, wyświetlając widok internetowy, w którym użytkownik może wpisać swoje dane logowania.
Aby rozpocząć proces logowania, wywołaj
signInWithProvider:firebase::Future<firebase::auth::AuthResult> result = auth->SignInWithProvider(provider_data);Aplikacja może wtedy poczekać lub zarejestrować wywołanie zwrotne w przyszłości.
Tego samego wzorca można używać z
ReauthenticateWithProvider, aby pobierać nowe dane logowania do operacji wrażliwych, które wymagają niedawnego logowania.firebase::Future<firebase::auth::AuthResult> result = user.ReauthenticateWithProvider(provider_data);Aplikacja może wtedy poczekać lub zarejestrować wywołanie zwrotne w przyszłości.
Możesz też użyć
LinkWithCredential(), aby połączyć różnych dostawców tożsamości z istniejącymi kontami.Pamiętaj, że Apple wymaga uzyskania wyraźnej zgody użytkowników przed połączeniem ich kont Apple z innymi danymi.
Aby na przykład połączyć konto na Facebooku z bieżącym kontem Firebase, użyj tokena dostępu uzyskanego podczas logowania użytkownika na Facebooku:
// Initialize a Facebook credential with a Facebook access token. AuthCredential credential = firebase::auth::FacebookAuthProvider.getCredential(token); // Assuming the current user is an Apple user linking a Facebook provider. firebase::Future<firebase::auth::AuthResult> result = auth.current_user().LinkWithCredential(credential);
Uwagi dotyczące logowania przez Apple
W przeciwieństwie do innych dostawców obsługiwanych przez Uwierzytelnianie Firebase Apple nie udostępnia adresu URL zdjęcia.
Gdy użytkownik zdecyduje się nie udostępniać swojego adresu e-mail aplikacji, Apple udostępnia mu unikalny adres e-mail (w formacie xyz@privaterelay.appleid.com), który udostępnia Twojej aplikacji. Jeśli skonfigurujesz usługę prywatnego przekazywania e-maili, Apple będzie przekazywać e-maile wysyłane na anonimowy adres na prawdziwy adres e-mail użytkownika.
Apple udostępnia aplikacjom informacje o użytkowniku, takie jak nazwa wyświetlana, tylko przy pierwszym logowaniu. Zwykle Firebase zapisuje nazwę wyświetlaną przy pierwszym logowaniu użytkownika przez Apple, którą możesz uzyskać za pomocą current_user().display_name(). Jeśli jednak wcześniej logowałeś(-aś) użytkownika w aplikacji za pomocą Apple bez użycia Firebase, Apple nie udostępni Firebase nazwy wyświetlanej użytkownika.
Dalsze kroki
Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z danymi logowania – nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania – za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane jako część projektu w Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od sposobu logowania.W aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu firebase::auth::User. Zobacz
Zarządzanie użytkownikami.
W regułach bezpieczeństwa bazy danych czasu rzeczywistego Firebase i Cloud Storage możesz uzyskać unikalny identyfikator użytkownika zalogowanego z zmiennej auth i użyć go do kontrolowania, do jakich danych użytkownik może mieć dostęp.