Uwierzytelniaj się za pomocą Apple i C++

Możesz zezwolić użytkownikom na uwierzytelnianie w Firebase przy użyciu ich Apple ID, używając pakietu Firebase SDK do przeprowadzania kompleksowego procesu logowania OAuth 2.0.

Zanim zaczniesz

Aby logować użytkowników za pomocą Apple, najpierw skonfiguruj Zaloguj się za pomocą Apple w witrynie programisty Apple, a następnie włącz Apple jako dostawcę logowania do projektu Firebase.

Dołącz do programu Apple Developer

Zaloguj się z Apple może być konfigurowane tylko przez członków firmy Apple Developer Program .

Skonfiguruj Zaloguj się za pomocą Apple

Logowanie Apple musi być włączone i poprawnie skonfigurowane w projekcie Firebase. Konfiguracja różni się w zależności od platform Android i Apple. Należy postępować zgodnie z „Konfiguracja Zaloguj się z Apple” sekcja platformy firmy Apple i / lub Android przewodników przed kontynuowaniem.

Włącz Apple jako dostawcę logowania

  1. W konsoli Firebase otwórz sekcję Auth. Na karcie Logowanie w metodzie umożliwienia usługodawcy firmy Apple.
  2. Skonfiguruj ustawienia dostawcy logowania Apple:
    1. 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.
    2. Wsparcie na urządzeniach z Androidem:
      1. Dodaj Firebase do projektu Android . Pamiętaj, aby zarejestrować podpis SHA-1 swojej aplikacji podczas konfigurowania aplikacji w konsoli Firebase.
      2. W konsoli Firebase otwórz sekcję Auth. Na karcie Logowanie w metodzie umożliwienia usługodawcy firmy Apple. Podaj identyfikator usługi utworzony w poprzedniej sekcji. Ponadto w sekcji konfiguracji przepływu kodu OAuth określ identyfikator zespołu Apple oraz klucz prywatny i identyfikator klucza utworzony w poprzedniej sekcji.

Przestrzegaj wymagań Apple dotyczących anonimowych danych

Zaloguj się z Apple daje użytkownikom możliwość anonimizujących swoich danych, w tym adresu e-mail, podczas logowania się. Użytkownicy, którzy wybiorą tę opcję mają adresy e-mail z domeny privaterelay.appleid.com . Korzystając z funkcji Zaloguj się przez Apple w swojej aplikacji, musisz przestrzegać wszelkich obowiązujących zasad lub warunków dla programistów Apple dotyczących tych anonimowych identyfikatorów Apple ID.

Obejmuje to uzyskanie wymaganej zgody użytkownika przed powiązaniem jakichkolwiek bezpośrednio identyfikujących danych osobowych z anonimowym identyfikatorem Apple ID. Podczas korzystania z Uwierzytelniania Firebase może to obejmować następujące czynności:

  • Połącz adres e-mail z anonimowym identyfikatorem Apple ID lub odwrotnie.
  • Połącz numer telefonu z anonimowym identyfikatorem Apple ID lub odwrotnie
  • Połącz nieanonimowe dane logowania społecznościowego (Facebook, Google itp.) z anonimowym identyfikatorem Apple ID lub odwrotnie.

Powyższa lista nie jest wyczerpująca. Zapoznaj się z Umową licencyjną programu Apple Developer w sekcji Członkostwo swojego konta programisty, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.

Uzyskaj dostęp do firebase::auth::Auth klasę

Auth klasa jest bramą do wszystkich wywołań API.
  1. Dodaj pliki nagłówka uwierzytelniania i aplikacji:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. W kodzie inicjującym utwórz firebase::App klasy.
    #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__)
    
  3. Nabyć firebase::auth::Auth klasę dla firebase::App . Istnieje odwzorowanie jeden do jednego między App i Auth .
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

Obsługuj proces logowania za pomocą pakietu Firebase SDK

Proces logowania się za pomocą Apple różni się w zależności od platform Apple i Android.

Na platformach Apple

Uwierzytelnij swoich użytkowników w Firebase za pomocą pakietu Apple Sign In Objective-C SDK wywoływanego z kodu C++.

  1. Dla każdego żądania logowania wygeneruj losowy ciąg — „nonce” — którego użyjesz, aby upewnić się, że otrzymany token identyfikatora został przyznany w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten krok jest ważny, aby zapobiec atakom typu powtórka.

      - (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 jednorazowy skrót SHA256, który Apple przekaże bez zmian w odpowiedzi. Firebase weryfikuje odpowiedź, haszując oryginalny numer jednorazowy i porównując go z wartością przekazaną przez Apple.

  2. Uruchom przepływ logowania Apple, w tym w swoim żądaniu hash SHA256 identyfikatora jednorazowego i klasę delegata, która obsłuży 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;
      }
    
  3. Obsłuż odpowiedź Apple podczas implementacji ASAuthorizationControllerDelegate`. Jeśli logowanie się powiodło, użyj tokena ID z odpowiedzi Apple z niezaszyfrowanym jednorazem, 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);
          }
        }
    
  4. Użyj otrzymanego ciągu tokena i oryginalnego identyfikatora, aby utworzyć poświadczenia Firebase i zalogować się do Firebase.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  5. Ten sam wzór może być stosowany do Reauthenticate , które mogą być wykorzystywane do pobierania świeże poświadczenia dla wrażliwych operacji, które wymagają ostatnie logowanie.

    firebase::Future<firebase::auth::SignInResult> result =
        user->Reauthenticate(credential);
    
  6. Ten sam wzór może być użyty do połączenia konta z Apple Sign In. Możesz jednak napotkać błąd, gdy istniejące konto Firebase zostało już połączone z kontem Apple, z którym próbujesz się połączyć. Gdy to nastąpi w przyszłości wróci do stanu kAuthErrorCredentialAlreadyInUse i obiekt UserInfo z SignInResult może zawierać poprawny updated_credential . Ten poświadczeń może być użyty do podpisania w Apple połączonego konta poprzez SignInWithCredential bez konieczności generowania drugie jabłko Zaloguj się żeton i nonce.

    Należy pamiętać, że trzeba użyć LinkAndRetrieveDataWithCredential dla tej operacji zawierać poświadczenie jako updated_credential jest członkiem SignInResult.UserInfo obiektu.

    firebase::Future<firebase::auth::SignInResult> link_result =
        auth->current_user()->LinkAndRetrieveDataWithCredential(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()->info.updated_credential.is_valid()) {
      // Sign In with the new credential
      firebase::Future<firebase::auth::User*> result = auth->SignInWithCredential(
          link_result.result()->info.updated_credential);
    } else {
      // Another link error occurred.
    }
    

Na Androidzie

W systemie Android uwierzytelniaj użytkowników za pomocą Firebase, integrując w swojej aplikacji ogólne internetowe logowanie OAuth przy użyciu pakietu SDK Firebase, aby przeprowadzić pełny proces logowania.

Aby obsłużyć proces logowania za pomocą pakietu Firebase SDK, wykonaj te czynności:

  1. Skonstruować instancję FederatedOAuthProviderData skonfigurowanych z odpowiednim dostawcą dla Apple ID.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. Opcjonalnie: określić dodatkowe zakresy OAuth 2.0 poza domyślnym że chcesz wniosek dostawcy uwierzytelniania.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. Opcjonalnie: Jeśli chcesz wyświetlić Apple ekranu logowania w języku innym niż angielski, należy ustawić locale parametru. Zobacz Zaloguj się z docs firmy Apple dla obsługiwanych lokalizacji.

    // Localize to French.
    provider_data.custom_parameters["language"] = "fr";
    ```
    
  4. Po skonfigurowaniu danych dostawcy użyj ich do utworzenia FederatedOAuthProvider.

    // Construct a FederatedOAuthProvider for use in Auth methods.
    firebase::auth::FederatedOAuthProvider provider(provider_data);
    
  5. Uwierzytelnij się w Firebase przy użyciu obiektu dostawcy uwierzytelniania. Pamiętaj, że w przeciwieństwie do innych operacji FirebaseAuth ta funkcja przejmie kontrolę nad interfejsem użytkownika, wyświetlając widok internetowy, w którym użytkownik może wprowadzić swoje dane logowania.

    Aby rozpocząć znak w strumieniu, zadzwoń signInWithProvider :

    firebase::Future<firebase::auth::SignInResult> result =
      auth->SignInWithProvider(provider_data);
    

    Aplikacja może następnie poczekać lub zarejestrować wywołania zwrotnego na przyszłość .

  6. Ten sam wzór może być stosowany z ReauthenticateWithProvider które mogą być wykorzystywane do pobierania świeże poświadczenia dla wrażliwych operacji, które wymagają ostatnie logowanie.

    firebase::Future<firebase::auth::SignInResult> result =
      user->ReauthenticateWithProvider(provider_data);
    

    Aplikacja może następnie poczekać lub zarejestrować wywołania zwrotnego na przyszłość .

  7. I można użyć linkWithCredential() do połączenia różnych dostawców tożsamości do istniejących kont.

    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 Facebook z bieżącym kontem Firebase, użyj tokena dostępu, który otrzymałeś po zalogowaniu użytkownika do Facebooka:

    // 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::SignInResult> result =
        auth.getCurrentUser().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, gdy użytkownik nie zdecyduje się udostępnić swoją pocztę z aplikacji, przepisy Jabłko unikalny adres e-mail do tego użytkownika (formy xyz@privaterelay.appleid.com ), którą dzieli z aplikacji. Jeśli skonfigurowałeś usługę przekazywania prywatnych wiadomości e-mail, Apple przekazuje wiadomości e-mail wysyłane na anonimowy adres na prawdziwy adres e-mail użytkownika.

Jabłko informacje wyłącznie akcje użytkownika, takich jak nazwa wyświetlacza z aplikacji po raz pierwszy użytkownik loguje się. Zazwyczaj Firebase przechowuje nazwę wyświetlaną po raz pierwszy użytkownik loguje się z Apple, które można uzyskać z getCurrentUser().getDisplayName() . Jeśli jednak wcześniej logowałeś użytkownika do aplikacji za pomocą Apple bez użycia 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 połączone z poświadczeniami — czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania — przy użyciu których użytkownik się zalogował. To nowe konto jest przechowywane jako część projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się on loguje.

W swoich aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu firebase::auth::user. Patrz Zarządzanie użytkownikami .

W regułach zabezpieczeń bazy danych czasu rzeczywistego i usługi Cloud Storage Firebase możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i używać go do kontrolowania, do jakich danych użytkownik ma dostęp.