Możesz pozwolić użytkownikom na uwierzytelnianie w Firebase przy użyciu ich Apple ID, korzystając z pakietu SDK Firebase do przeprowadzania kompleksowego procesu logowania OAuth 2.0.
Zanim zaczniesz
Aby zalogować użytkowników za pomocą Apple, najpierw skonfiguruj opcję Zaloguj się przez Apple w witrynie programistów Apple, a następnie włącz firmę Apple jako dostawcę logowania dla swojego projektu Firebase.
Dołącz do programu deweloperskiego Apple
Logowanie za pomocą konta Apple mogą konfigurować wyłącznie członkowie programu Apple Developer Program .
Skonfiguruj logowanie za pomocą Apple
Logowanie Apple musi być włączone i odpowiednio skonfigurowane w projekcie Firebase. Konfiguracja różni się w zależności od platformy Android i Apple. Przed kontynuowaniem postępuj zgodnie z sekcją „Konfiguruj logowanie za pomocą Apple” w przewodnikach dotyczących platform Apple i/lub Androida .Włącz firmę Apple jako dostawcę logowania
- W konsoli Firebase otwórz sekcję Uwierzytelnianie . Na karcie Metoda logowania włącz dostawcę Apple .
- Skonfiguruj ustawienia dostawcy logowania Apple:
- Jeśli wdrażasz aplikację tylko na platformach Apple, możesz pozostawić pola Identyfikator usługi, Identyfikator zespołu Apple, Klucz prywatny i Identyfikator klucza puste.
- Aby uzyskać pomoc na urządzeniach z Androidem:
- Dodaj Firebase do swojego projektu na Androida . Pamiętaj, aby zarejestrować podpis SHA-1 swojej aplikacji podczas konfigurowania aplikacji w konsoli Firebase.
- W konsoli Firebase otwórz sekcję Uwierzytelnianie . Na karcie Metoda logowania włącz dostawcę Apple . Określ identyfikator usługi utworzony w poprzedniej sekcji. Ponadto w sekcji konfiguracji przepływu kodu OAuth podaj identyfikator zespołu Apple oraz klucz prywatny i identyfikator klucza utworzone w poprzedniej sekcji.
Spełniaj wymagania Apple dotyczące anonimowych danych
Zaloguj się przez Apple daje użytkownikom możliwość anonimizacji swoich danych, w tym adresu e-mail, podczas logowania. Użytkownicy, którzy wybiorą tę opcję, mają adresy e-mail w domenie privaterelay.appleid.com
. Korzystając w aplikacji z funkcji Zaloguj się przez Apple, musisz przestrzegać wszelkich obowiązujących zasad i warunków programistycznych Apple dotyczących tych anonimowych identyfikatorów Apple ID.
Obejmuje to uzyskanie wymaganej zgody użytkownika przed powiązaniem jakichkolwiek danych osobowych bezpośrednio identyfikujących z zanonimizowanym identyfikatorem Apple ID. W przypadku korzystania z uwierzytelniania Firebase może to obejmować następujące działania:
- Połącz adres e-mail z anonimowym identyfikatorem Apple ID i odwrotnie.
- Połącz numer telefonu z anonimowym identyfikatorem Apple ID i odwrotnie
- Połącz nieanonimowe dane uwierzytelniające w mediach społecznościowych (Facebook, Google itp.) z anonimowym identyfikatorem Apple ID i odwrotnie.
Powyższa lista nie jest wyczerpująca. Zapoznaj się z Umową licencyjną programu Apple Developer w sekcji Członkostwo na swoim koncie programisty, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.
Uzyskaj dostęp do klasy firebase::auth::Auth
Klasa Auth
jest bramą dla wszystkich wywołań API.- Dodaj pliki nagłówkowe Auth i App:
#include "firebase/app.h" #include "firebase/auth.h"
- W kodzie inicjującym utwórz klasę
firebase::App
.#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__)
- Zdobądź klasę
firebase::auth::Auth
dla swojejfirebase::App
. Istnieje mapowanie jeden do jednego pomiędzyApp
iAuth
.firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
Obsługuj proces logowania za pomocą pakietu SDK Firebase
Proces logowania się za pomocą konta Apple różni się w zależności od platformy Apple i Android.
Na platformach Apple
Uwierzytelnij swoich użytkowników w Firebase za pomocą zestawu SDK Apple Sign In Objective-C wywoływanego z kodu C++.
Dla każdego żądania logowania wygeneruj losowy ciąg znaków — „nonce” — którego użyjesz, aby upewnić się, że otrzymany token identyfikacyjny został przyznany konkretnie w odpowiedzi na żądanie uwierzytelnienia Twojej aplikacji. Ten krok jest ważny, aby zapobiec atakom poprzez powtórzenie.
- (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--; } } } }
Wraz z żądaniem logowania wyślesz skrót SHA256 wartości jednorazowej, który Apple przekaże w odpowiedzi bez zmian. Firebase sprawdza odpowiedź, mieszając oryginalną wartość jednorazową i porównując ją z wartością przekazaną przez Apple.
Rozpocznij proces logowania Apple, dołączając w swoim żądaniu skrót SHA256 wartości jednorazowej i klasę delegata, która będzie obsługiwać odpowiedź Apple (zobacz 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ługuj odpowiedź Apple w implementacji ASAuthorizationControllerDelegate`. Jeśli logowanie się powiodło, użyj tokena identyfikacyjnego z odpowiedzi Apple z niezaszyfrowaną wartością jednorazową, aby uwierzytelnić się 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 powstałego ciągu tokena i oryginalnej wartości jednorazowej, aby utworzyć dane uwierzytelniające Firebase i zalogować się do 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żyć w przypadku
Reauthenticate
, którego można użyć do pobrania nowych poświadczeń dla wrażliwych operacji wymagających niedawnego logowania.firebase::Future<firebase::auth::AuthResult> result = user->Reauthenticate(credential);
Tego samego wzoru można użyć do połączenia konta z Apple Sign In. Może jednak wystąpić błąd, gdy istniejące konto Firebase zostało już połączone z kontem Apple, z którym próbujesz się połączyć. Kiedy to nastąpi, przyszłość zwróci status
kAuthErrorCredentialAlreadyInUse
, aAuthResult
może zawierać prawidłowecredential
. Tego poświadczenia można użyć do zalogowania się na konto połączone z Apple za pośrednictwemSignInAndRetrieveDataWithCredential
bez konieczności generowania kolejnego tokena logowania Apple i jednorazowego użytku.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. }
Na Androidzie
Na Androidzie uwierzytelniaj swoich użytkowników w Firebase, integrując internetowe standardowe logowanie OAuth ze swoją aplikacją za pomocą pakietu Firebase SDK, aby przeprowadzić kompleksowy proces logowania.
Aby obsłużyć proces logowania za pomocą pakietu SDK Firebase, wykonaj następujące kroki:
Utwórz instancję
FederatedOAuthProviderData
skonfigurowaną z identyfikatorem dostawcy odpowiednim dla firmy Apple.firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 poza domyślnymi, których chcesz zażądać od dostawcy uwierzytelniania.
provider_data.scopes.push_back("email"); provider_data.scopes.push_back("name");
Opcjonalnie: Jeśli chcesz, aby ekran logowania Apple był wyświetlany w języku innym niż angielski, ustaw parametr
locale
. Aby zapoznać się z obsługiwanymi ustawieniami regionalnymi, zapoznaj się z dokumentacją Logowanie przy użyciu konta Apple .// Localize to French. provider_data.custom_parameters["language"] = "fr"; ```
Po skonfigurowaniu danych dostawcy użyj ich do utworzenia FederatedOAuthProvider.
// Construct a FederatedOAuthProvider for use in Auth methods. firebase::auth::FederatedOAuthProvider provider(provider_data);
Uwierzytelnij się w Firebase przy użyciu obiektu dostawcy uwierzytelniania. Pamiętaj, że w przeciwieństwie do innych operacji FirebaseAuth, ta przejmie kontrolę nad Twoim interfejsem użytkownika, wyświetlając widok internetowy, w którym użytkownik może wprowadzić swoje dane uwierzytelniające.
Aby rozpocząć proces logowania, wywołaj funkcję
signInWithProvider
:firebase::Future<firebase::auth::AuthResult> result = auth->SignInWithProvider(provider_data);
Twoja aplikacja może wtedy poczekać lub zarejestrować oddzwonienie w Future .
Tego samego wzorca można użyć z
ReauthenticateWithProvider
, którego można użyć do pobrania nowych poświadczeń dla poufnych operacji wymagających niedawnego logowania.firebase::Future<firebase::auth::AuthResult> result = user.ReauthenticateWithProvider(provider_data);
Twoja aplikacja może wtedy poczekać lub zarejestrować oddzwonienie w Future .
Możesz także 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.
Na przykład, aby połączyć konto na Facebooku z bieżącym kontem Firebase, użyj tokena dostępu otrzymanego 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);
Zaloguj się za pomocą Apple Notes
W przeciwieństwie do innych dostawców obsługiwanych przez Firebase Auth, Apple nie udostępnia adresu URL zdjęcia.
Ponadto, jeśli użytkownik zdecyduje się nie udostępniać aplikacji swojego adresu e-mail, Apple przydziela temu użytkownikowi unikalny adres e-mail (w postaci xyz@privaterelay.appleid.com
), który udostępnia Twojej aplikacji. Jeśli skonfigurowałeś usługę przekazywania prywatnych wiadomości e-mail, Apple przekazuje wiadomości e-mail wysł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 przechowuje nazwę wyświetlaną przy pierwszym logowaniu się użytkownika do Apple, co można uzyskać za pomocą current_user().display_name()
. Jeśli jednak wcześniej korzystałeś z usługi Apple do logowania użytkownika w aplikacji bez korzystania z Firebase, Apple nie udostępni Firebase nazwy wyświetlanej użytkownika.
Następne kroki
Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i powiązane z poświadczeniami — czyli 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ęść Twojego projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w Twoim projekcie, niezależnie od tego, w jaki sposób użytkownik się loguje. W Twoich 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 Firebase Realtime i Cloud Storage możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auty i użyć go do kontrolowania, do jakich danych użytkownik może uzyskać dostęp.