Uwierzytelnij przez Apple i C++

Aby zezwolić użytkownikom na uwierzytelnianie w Firebase za pomocą ich Apple ID: używając pakietu SDK Firebase do przeprowadzenia pełnego logowania OAuth 2.0.

Zanim zaczniesz

Aby zalogować użytkowników przy użyciu urządzenia Apple, najpierw skonfiguruj funkcję Zaloguj się przez Apple w witrynie Apple dla deweloperów, a potem włącz Apple jako dostawcę logowania projekt Firebase.

Dołącz do programu dla deweloperów Apple

Funkcja Zaloguj się przez Apple może skonfigurować tylko członkowie Apple Developer Program.

Skonfiguruj logowanie się przez Apple

Musisz włączyć i prawidłowo skonfigurować logowanie przez Apple w swoim projekcie Firebase. Konfiguracja różni się w zależności od platformy Android i platformy Apple. Postępuj zgodnie z „Skonfiguruj logowanie się przez Apple” sekcji Platformy Apple lub Przewodniki dotyczące Androida przed dalej.

Włącz Apple jako dostawcę logowania

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie. Na karcie Metoda logowania: włącz dostawcę Apple.
  2. Skonfiguruj ustawienia dostawcy logowania przez 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 są puste.
    2. Aby uzyskać pomoc dotyczącą urządzeń z Androidem:
      1. Dodaj Firebase do swojego projektu na Androida. Bądź Pamiętaj, aby zarejestrować podpis SHA-1 swojej aplikacji podczas konfigurowania konsoli Firebase.
      2. W Firebase konsolę, otwórz sekcję Auth (Uwierzytelnianie). Na karcie Metoda logowania: włącz dostawcę Apple. Podaj identyfikator usługi utworzony w narzędziu poprzedniej sekcji. Ponadto w sekcji konfiguracji przepływu kodu OAuth podaj identyfikator zespołu Apple oraz klucz prywatny i identyfikator utworzonego klucza w poprzedniej sekcji.

Zgodność z wymaganiami firmy Apple dotyczącymi zanonimizowanych danych

Zaloguj się przez Apple umożliwia anonimizację danych użytkowników, łącznie z jego adresem e-mail. Użytkownicy, którzy wybiorą tę opcję mają adresy e-mail w domenie privaterelay.appleid.com. Kiedy korzystasz w aplikacji z funkcji Zaloguj się przez Apple, musisz przestrzegać wszystkich obowiązujących zasady dla deweloperów lub warunki firmy Apple dotyczące tych zanonimizowanych Identyfikatory.

Obejmuje to uzyskanie wymaganej zgody użytkownika przed kojarzyć żadnych danych osobowych bezpośrednio umożliwiających identyfikację ze zanonimizowanymi danymi firmy Apple ID. Gdy korzystasz z Uwierzytelniania Firebase, może to obejmować: czynności:

  • Połącz adres e-mail z anonimowym identyfikatorem Apple ID lub odwrotnie.
  • Łączenie numeru telefonu z anonimowym identyfikatorem Apple ID i odwrotnie
  • Połącz nieanonimowe dane społecznościowe (Facebook, Google itp.) z lub na odwrót.

Powyższa lista nie jest wyczerpująca. Zapoznaj się z informacjami o programie dla deweloperów Apple Umowy licencyjnej w sekcji Członkostwo na koncie dewelopera, aby aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.

Uzyskaj dostęp do zajęć firebase::auth::Auth

Klasa Auth jest bramą dla wszystkich wywołań interfejsu API.
  1. Dodaj pliki nagłówka Auth i App:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. W kodzie inicjowania utwórz 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__)
    
  3. Uzyskaj zajęcia firebase::auth::Auth związane z urządzeniem firebase::App. Między App a Auth występuje mapowanie 1:1.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

Zarejestruj się za pomocą pakietu SDK Firebase

Proces logowania się 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ą logowania Apple Pakiet SDK Objective-C został wywołany z kodu w C++.

  1. Dla każdego żądania logowania wygeneruj losowy ciąg znaków, „nonce” – służy do sprawdzenia, czy otrzymany token przyznanych w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten 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 wysyłasz hasz SHA256 identyfikatora jednorazowego, który Apple przekazuje w odpowiedzi niezmienioną treść. Firebase weryfikuje odpowiedź. przez zaszyfrowanie oryginalnej liczby jednorazowej i porównanie jej z wartością przekazaną przez Apple.

  2. Uruchom proces logowania Apple, uwzględnij w żądaniu identyfikator SHA256 liczbę jednorazową 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;
      }
    
  3. Obsłuż odpowiedź Apple w swojej implementacji ASAuthorizationControllerDelegate`. Jeśli udało Ci się zalogować, użyj identyfikatora token z odpowiedzi Apple z niezaszyfrowaną liczbą jednorazową do uwierzytelnienia 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 powstałego ciągu tokena i oryginalnej wartości jednorazowej do utworzenia Firebase Zaloguj się w Firebase i zaloguj.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  5. Tego samego wzorca można użyć w obiekcie Reauthenticate, który może być służy do pobierania nowych danych logowania na potrzeby operacji poufnych, które wymagają ostatniego logowania.

    firebase::Future<firebase::auth::AuthResult> result =
        user->Reauthenticate(credential);
    
  6. Tego samego wzoru można użyć do połączenia konta z Apple Sign In. Może jednak wystąpić błąd, jeśli na istniejącym koncie Firebase są już połączone z kontem Apple, z którym próbujesz utworzyć powiązanie. W takim przypadku przyszłość zwraca stan kAuthErrorCredentialAlreadyInUse i AuthResult mogą zawierać prawidłowe credential Tych danych można używać do logowania się za pośrednictwem usługi SignInAndRetrieveDataWithCredential bez konieczności wygenerować inny token i jednorazową wartość logowania 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

Uwierzytelniaj użytkowników w Androidzie za pomocą Firebase, integrując do aplikacji ogólnego logowania OAuth za pomocą pakietu SDK Firebase, aby zakończyć proces logowania.

Aby zalogować się za pomocą pakietu SDK Firebase, wykonaj te czynności:

  1. Utwórz instancję instancji FederatedOAuthProviderData skonfigurowaną za pomocą identyfikator dostawcy odpowiedni dla Apple.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 oprócz domyślnych których chcesz uzyskać od dostawcy uwierzytelniania.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. Opcjonalnie: jeśli chcesz wyświetlać ekran logowania Apple w wybranym języku inny niż angielski, ustaw parametr locale. Zobacz Logowanie się przez Dokumenty Apple w obsługiwanych językach.

    // 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. Uwierzytelniaj w Firebase za pomocą obiektu dostawcy uwierzytelniania. Pamiętaj, że w przeciwieństwie do inne operacje FirebaseAuth, przejmie ono kontrolę nad interfejsem użytkownika, otwórz widok internetowy, w którym użytkownik może wpisać swoje dane logowania.

    Aby rozpocząć procedurę logowania, zadzwoń pod numer signInWithProvider:

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

    Następnie należy zaczekać zarejestrować oddzwonienie w przyszłości.

  6. Tego samego wzorca można użyć w obiekcie ReauthenticateWithProvider, który może być służy do pobierania nowych danych logowania na potrzeby operacji poufnych, które wymagają ostatniego logowania.

    firebase::Future<firebase::auth::AuthResult> result =
      user.ReauthenticateWithProvider(provider_data);
    

    Aplikacja może zaczekać lub zarejestrować oddzwonienie przyszłości.

  7. Za pomocą LinkWithCredential() możesz też łączyć różnych dostawców tożsamości z istniejącymi kontami.

    Pamiętaj, że firma Apple wymaga uzyskania wyraźnej zgody użytkowników przed połączyć swoje konta Apple z innymi danymi.

    Aby na przykład połączyć konto na Facebooku z bieżącym kontem Firebase, token dostępu uzyskany po zalogowaniu 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ę przez Apple Notes

W przeciwieństwie do innych dostawców obsługiwanych przez Uwierzytelnienie Firebase Apple nie udostępnia adresu URL zdjęcia.

Ponadto, jeśli użytkownik zdecyduje się nie udostępniać aplikacji e-mail, Apple udostępnia danemu użytkownikowi niepowtarzalny adres e-mail (w formie formularza xyz@privaterelay.appleid.com), które udostępnia Twojej aplikacji. Jeśli jeśli skonfigurowano usługę prywatnego przekaźnika poczty e-mail, Apple przekazuje e-maile wysyłane na zanonimizowany adres do rzeczywistego adresu e-mail użytkownika.

Apple udostępnia informacje o użytkowniku, takie jak wyświetlana nazwa, aplikacjom przy pierwszym logowaniu się użytkownika. Zwykle Firebase przechowuje wyświetlaną nazwę przy pierwszym logowaniu się w Apple. Dzięki temu current_user().display_name() Jeśli jednak wcześniej podpisałeś(-aś) się za pomocą Apple do aplikacji, którzy nie korzystają z Firebase, Apple nie udostępni tej aplikacji Firebase z nazwą wyświetlaną użytkownika.

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, tworzone jest nowe konto użytkownika. powiązane z danymi logowania, czyli nazwa użytkownika, hasło, numer telefonu lub informacje o dostawcy uwierzytelniania – użytkownik zalogowany. To nowe konto jest zapisane jako w ramach projektu Firebase. Może służyć do identyfikowania użytkownika w każdym aplikacji w projekcie niezależnie od tego, jak użytkownik się loguje.

W swoich aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z firebase::auth::User obiekt. Zobacz Zarządzanie użytkownikami

W Bazie danych czasu rzeczywistego Firebase i Regułach zabezpieczeń Cloud Storage możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej uwierzytelniania. kontrolować dostęp użytkownika do danych.