Mit Apple und C++ authentifizieren

Sie können Ihren Nutzern die Authentifizierung mit Firebase über ihre Apple-ID ermöglichen. Verwenden Sie dazu das Firebase SDK, um den OAuth 2.0-Anmeldeablauf von Anfang bis Ende auszuführen.

Hinweis

Wenn Sie Nutzer über Apple anmelden möchten, konfigurieren Sie zuerst „Mit Apple anmelden“ auf der Apple-Entwicklerwebsite und aktivieren Sie dann Apple als Anmeldeanbieter für Ihr Firebase-Projekt.

Am Apple-Entwicklerprogramm teilnehmen

„Mit Apple anmelden“ kann nur von Mitgliedern des Apple Developer Programms konfiguriert werden.

„Mit Apple anmelden“ konfigurieren

„Mit Apple anmelden“ muss in Ihrem Firebase-Projekt aktiviert und richtig konfiguriert sein. Die Konfiguration variiert je nach Android- und Apple-Plattform. Bitte folgen Sie dem Abschnitt „Mit Apple anmelden konfigurieren“ der Apple-Plattformen und/oder Android-Leitfäden, bevor Sie fortfahren.

Apple als Anmeldeanbieter aktivieren

  1. Wechseln Sie in der Firebase Console zu Security > Authentication.
  2. Aktivieren Sie auf dem Tab Anmeldemethode den Anmeldeanbieter Apple sign-in provider.
  3. Konfigurieren Sie die Einstellungen für den Anmeldeanbieter „Mit Apple anmelden“:
    • Apple: Wenn Sie Ihre App nur auf Apple Plattformen bereitstellen, können Sie die Felder „Dienst-ID“, „Apple-Team-ID“, „Privater Schlüssel“ und „Schlüssel-ID“ leer lassen.
    • Android: Führen Sie die folgenden Schritte aus, um Android-Geräte zu unterstützen:
      1. Fügen Sie Ihrem Android-Projekt Firebase hinzu.
      2. Geben Sie den SHA-1-Fingerabdruck Ihrer App an, falls noch nicht geschehen.
        1. Wechseln Sie in der Firebase Console zu den Einstellungen > Tab Allgemein.
        2. Scrollen Sie nach unten zur Karte Ihre Apps , wählen Sie Ihre Android-App aus und fügen Sie Ihren SHA-1-Fingerabdruck in das Feld SHA-Zertifikat-Fingerabdrücke ein.

        Unter Client authentifizieren finden Sie weitere Informationen zum Abrufen des SHA-Fingerabdrucks Ihrer App.

      3. Konfigurieren Sie die Einstellungen für den Anmeldeanbieter „Mit Apple anmelden“:
        1. Wechseln Sie in der Firebase Console zu Sicherheit > Authentifizierung.
        2. Klicken Sie auf dem Tab Anmeldemethode auf den Anmeldeanbieter Apple.
        3. Geben Sie die Dienst-ID an, die Sie im vorherigen Abschnitt erstellt haben. Geben Sie im Konfigurationsbereich für den OAuth-Codeablauf außerdem Ihre Apple-Team-ID sowie den privaten Schlüssel und die Schlüssel-ID an, die Sie im vorherigen Abschnitt erstellt haben.

Anforderungen von Apple für anonymisierte Daten einhalten

„Mit Apple anmelden“ bietet Nutzern die Möglichkeit, ihre Daten, einschließlich ihrer E-Mail-Adresse, bei der Anmeldung zu anonymisieren. Nutzer, die diese Option auswählen, haben E-Mail-Adressen mit der Domain privaterelay.appleid.com. Wenn Sie „Mit Apple anmelden“ in Ihrer App verwenden, müssen Sie alle geltenden Entwicklerrichtlinien oder ‑bedingungen von Apple bezüglich dieser anonymisierten Apple-IDs einhalten.

Dazu gehört, dass Sie die erforderliche Nutzereinwilligung einholen, bevor Sie direkt identifizierbare personenbezogene Daten mit einer anonymisierten Apple-ID verknüpfen. Bei Verwendung von Firebase Authentication können folgende Aktionen erforderlich sein:

  • E-Mail-Adresse mit einer anonymisierten Apple-ID verknüpfen und umgekehrt
  • Telefonnummer mit einer anonymisierten Apple-ID verknüpfen und umgekehrt
  • Nicht anonyme Anmeldedaten für soziale Medien (Facebook, Google usw.) mit einer anonymisierten Apple-ID verknüpfen und umgekehrt

Die obige Liste ist nicht vollständig. Beachten Sie die Lizenzvereinbarung des Apple-Entwicklerprogramms im Mitgliedschaftsbereich Ihres Entwicklerkontos, um sicherzustellen, dass Ihre App die Anforderungen von Apple erfüllt.

Auf die Klasse firebase::auth::Auth zugreifen

Die Klasse Auth ist das Gateway für alle API-Aufrufe.
  1. Fügen Sie die Headerdateien „Auth“ und „App“ hinzu:
    #include "firebase/app.h"
    #include "firebase/auth.h"
  2. Erstellen Sie in Ihrem Initialisierungscode eine firebase::App-Klasse.
    #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. Rufen Sie die Klasse firebase::auth::Auth für Ihre firebase::App ab. Es gibt eine 1:1-Zuordnung zwischen App und Auth.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);

Anmeldeablauf mit dem Firebase SDK verarbeiten

Der Vorgang für die Anmeldung mit Apple variiert je nach Apple- und Android-Plattform.

Auf Apple-Plattformen

Authentifizieren Sie Ihre Nutzer mit Firebase über das Apple Sign In Objective-C SDK, das von Ihrem C++-Code aufgerufen wird.

  1. Generieren Sie für jede Anmeldeanfrage einen zufälligen String – eine „Nonce“ –, mit der Sie prüfen, ob das ID-Token, das Sie erhalten, speziell als Antwort auf die Authentifizierungsanfrage der Anwendung gewährt wurde. Dieser Schritt ist wichtig, um Wiederholungsversuche zu verhindern.

      - (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--;
            }
          }
        }
      }
    
    

    Sie senden den SHA256-Hash der Nonce mit Ihrer Anmeldeanfrage, die Apple in der Antwort unverändert übergibt. Firebase validiert die Antwort, indem die ursprüngliche Nonce gehasht und mit dem von Apple übergebenen Wert verglichen wird.

  2. Starten Sie den Anmeldevorgang von Apple und fügen Sie in Ihre Anfrage den SHA256-Hash der Nonce und die Delegate-Klasse ein, die die Antwort von Apple verarbeitet (siehe nächsten Schritt):

      - (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. Verarbeiten Sie die Antwort von Apple in Ihrer Implementierung von ASAuthorizationControllerDelegate`. Wenn die Anmeldung erfolgreich war, verwenden Sie das ID-Token aus der Antwort von Apple mit der nicht gehashten Nonce zur Authentifizierung bei 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. Verwenden Sie den resultierenden Token-String und die ursprüngliche Nonce, um Anmeldedaten für Firebase zu erstellen und sich in Firebase anzumelden.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  5. Dasselbe Muster kann mit Reauthenticate verwendet werden, um neue Anmeldedaten für vertrauliche Vorgänge abzurufen, für die eine aktuelle Anmeldung erforderlich ist.

    firebase::Future<firebase::auth::AuthResult> result =
        user->Reauthenticate(credential);
    
  6. Dasselbe Muster kann verwendet werden, um ein Konto mit „Mit Apple anmelden“ zu verknüpfen. Es kann jedoch ein Fehler auftreten, wenn ein vorhandenes Firebase-Konto bereits mit dem Apple-Konto verknüpft ist, mit dem Sie eine Verknüpfung herstellen möchten. In diesem Fall gibt die Future einen Status von kAuthErrorCredentialAlreadyInUse zurück und das AuthResult kann gültige credential enthalten. Mit diesen Anmeldedaten kann sich das mit Apple verknüpfte Konto über SignInAndRetrieveDataWithCredential anmelden, ohne dass ein weiteres „Mit Apple anmelden“-Token und eine weitere Nonce generiert werden müssen.

    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.
    }

Auf Android-Geräten

Authentifizieren Sie Ihre Nutzer auf Android-Geräten mit Firebase, indem Sie die webbasierte generische OAuth-Anmeldung in Ihre App einbinden. Verwenden Sie dazu das Firebase SDK, um den Anmeldeablauf von Anfang bis Ende auszuführen.

So verarbeiten Sie den Anmeldeablauf mit dem Firebase SDK:

  1. Erstellen Sie eine Instanz von FederatedOAuthProviderData, die mit der für Apple geeigneten Anbieter-ID konfiguriert ist.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. Optional:Geben Sie zusätzliche OAuth 2.0-Bereiche an, die über die Standardbereiche hinausgehen und die Sie vom Authentifizierungsanbieter anfordern möchten.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. Optional:Wenn Sie den Anmeldebildschirm von Apple in einer anderen Sprache als Englisch anzeigen möchten, legen Sie den Parameter locale fest. Unter „Mit Apple anmelden“ finden Sie die unterstützten Gebietsschemas.

    // Localize to French.
    provider_data.custom_parameters["language"] = "fr";
    ```
    
  4. Nachdem Sie Ihre Anbieterdaten konfiguriert haben, erstellen Sie damit einen FederatedOAuthProvider.

    // Construct a FederatedOAuthProvider for use in Auth methods.
    firebase::auth::FederatedOAuthProvider provider(provider_data);
    
  5. Authentifizieren Sie sich mit Firebase über das Auth-Anbieterobjekt. Im Gegensatz zu anderen FirebaseAuth-Vorgängen übernimmt dieser Vorgang die Steuerung der UI, indem eine Webansicht eingeblendet wird, in der der Nutzer seine Anmeldedaten eingeben kann.

    Rufen Sie signInWithProvider auf, um den Anmeldeablauf zu starten:

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

    Ihre Anwendung kann dann warten oder einen Callback für die Future registrieren.

  6. Dasselbe Muster kann mit ReauthenticateWithProvider verwendet werden, um neue Anmeldedaten für vertrauliche Vorgänge abzurufen, für die eine aktuelle Anmeldung erforderlich ist.

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

    Ihre Anwendung kann dann warten oder einen Callback für die Future registrieren.

  7. Mit LinkWithCredential() können Sie außerdem verschiedene Identitätsanbieter mit vorhandenen Konten verknüpfen.

    Apple verlangt, dass Sie die ausdrückliche Einwilligung der Nutzer einholen, bevor Sie ihre Apple-Konten mit anderen Daten verknüpfen.

    Wenn Sie beispielsweise ein Facebook-Konto mit dem aktuellen Firebase-Konto verknüpfen möchten, verwenden Sie das Zugriffstoken, das Sie durch die Anmeldung des Nutzers bei Facebook erhalten haben:

    // 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);
    

Hinweise zur Anmeldung mit Apple

Anders als andere von Firebase Auth unterstützte Anbieter stellt Apple keine Foto-URL bereit.

Wenn der Nutzer außerdem seine E-Mail-Adresse nicht mit der App teilen möchte, stellt Apple eine eindeutige E-Mail-Adresse für diesen Nutzer bereit (im Format xyz@privaterelay.appleid.com), die an Ihre App weitergegeben wird. Wenn Sie den privaten E-Mail-Relay-Dienst konfiguriert haben, leitet Apple alle an die anonymisierte Adresse gesendeten E-Mails an die reale E-Mail-Adresse des Nutzers weiter.

Apple gibt Nutzerinformationen wie den Anzeigenamen nur dann an Anwendungen weiter, wenn sich ein Nutzer zum ersten Mal anmeldet. Normalerweise speichert Firebase den Anzeigenamen, wenn sich ein Nutzer zum ersten Mal mit Apple anmeldet. Sie können ihn mit current_user().display_name() abrufen. Wenn Sie Apple jedoch zuvor verwendet haben, um einen Nutzer in der App anzumelden, ohne Firebase zu verwenden, stellt Apple Firebase den Anzeigenamen des Nutzers nicht zur Verfügung.

Nächste Schritte

Wenn sich ein Nutzer zum ersten Mal anmeldet, wird ein neues Nutzerkonto erstellt und mit den Anmeldedaten verknüpft, mit denen sich der Nutzer angemeldet hat (Nutzername und Passwort, Telefonnummer oder Informationen zum Authentifizierungsanbieter). Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Nutzer in allen Apps Ihres Projekts zu identifizieren, unabhängig davon, wie sich der Nutzer anmeldet.

In Ihren Apps können Sie die grundlegenden Profilinformationen des Nutzers aus dem Objekt firebase::auth::User abrufen. Weitere Informationen finden Sie unter Nutzer verwalten.

In den Sicherheitsregeln für die Firebase Realtime Database und Cloud Storage können Sie die eindeutige Nutzer-ID des angemeldeten Nutzers aus der Auth-Variablen abrufen und damit steuern, auf welche Daten ein Nutzer zugreifen kann.