S'authentifier avec Apple et C++

Vous pouvez autoriser vos utilisateurs à s'authentifier avec Firebase à l'aide de leur identifiant Apple en utilisant le SDK Firebase pour effectuer le flux de connexion OAuth 2.0 de bout en bout.

Avant de commencer

Pour connecter les utilisateurs avec Apple, configurez d'abord Se connecter avec Apple sur le site des développeurs Apple, puis activez Apple en tant que fournisseur de connexion pour votre projet Firebase.

Rejoindre l'Apple Developer Program

Seuls les membres de l'équipe Apple Developer peuvent configurer la fonctionnalité Se connecter avec Apple de sécurité.

Configurer la connexion avec Apple

Apple Sign In doit être activé et correctement configuré dans votre projet Firebase. La configuration varie selon les plates-formes Android et Apple. Veuillez suivre les Configurer la connexion avec Apple de la Plates-formes Apple et/ou Guides Android avant en cours.

Activer Apple en tant que fournisseur de connexion

  1. Dans la console Firebase, ouvrez la section Authentification. Dans l'onglet Méthode de connexion, activer le fournisseur Apple.
  2. Configurez les paramètres du fournisseur de connexion Apple :
    1. Si vous ne déployez votre application que sur des plates-formes Apple, vous pouvez laisser le Les champs "ID de service", "ID d'équipe Apple", "Clé privée" et "ID de clé" sont vides.
    2. Pour obtenir de l'aide sur les appareils Android: <ph type="x-smartling-placeholder">
        </ph>
      1. Ajoutez Firebase à votre projet Android. Être enregistrez la signature SHA-1 de votre application lorsque vous la configurez dans le Console Firebase.
      2. Dans la console Firebase, ouvrez la section Auth. Dans l'onglet Méthode de connexion, activer le fournisseur Apple. Indiquez l'ID de service que vous avez créé dans la section précédente. Dans la section "Configuration du flux de code OAuth", indiquez également votre ID d'équipe Apple, ainsi que la clé privée et l'ID de clé que vous avez créés dans la section précédente.

Respecter les exigences d'Apple concernant les données anonymisées

Se connecter avec Apple offre aux utilisateurs la possibilité d'anonymiser leurs données, y compris son adresse e-mail, lorsqu'il se connecte. Les utilisateurs qui choisissent cette option disposent d'adresses e-mail avec le domaine privaterelay.appleid.com. Quand ? que vous utilisez la fonctionnalité Se connecter avec Apple dans votre application, vous devez vous conformer aux les règles pour les développeurs ou les conditions d'utilisation d'Apple concernant ces données anonymisées ID.

Cela inclut l'obtention de l'autorisation de l'utilisateur avant d'associer des informations personnelles permettant de l'identifier directement à un identifiant Apple anonyme. Lorsque vous utilisez Firebase Authentication, cela peut inclure les éléments suivants : actions:

  • Associez une adresse e-mail à un identifiant Apple anonyme, ou inversement.
  • Associer un numéro de téléphone à un identifiant Apple anonyme, ou inversement
  • Associez un identifiant de réseau social non anonyme (Facebook, Google, etc.) à un un identifiant Apple anonyme, ou inversement.

La liste ci-dessus n'est pas exhaustive. Consulter l'Apple Developer Program dans la section "Abonnement" de votre compte de développeur assurez-vous que votre application répond aux exigences d'Apple.

Accéder à la classe firebase::auth::Auth

La classe Auth est la passerelle pour tous les appels d'API.
  1. Ajoutez les fichiers d'en-tête Auth et App :
    #include "firebase/app.h"
    #include "firebase/auth.h"
  2. Dans votre code d'initialisation, créez 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. Procurez-vous la classe firebase::auth::Auth pour votre firebase::App. Il existe un mappage de type "un à un" entre App et Auth.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);

Gérer le flux de connexion avec le SDK Firebase

La procédure de connexion avec Apple varie selon les plates-formes Apple et Android.

Sur les plates-formes Apple

Authentifiez vos utilisateurs avec Firebase via le SDK Objective-C Apple Sign In appelé à partir de votre code C++.

  1. Pour chaque demande de connexion, générez une chaîne aléatoire : "nonce", que vous utiliserez pour vous assurer que le jeton d'ID que vous obtenez a été accordé spécifiquement en réponse à la demande d'authentification de votre application. Cette étape est importante pour éviter les attaques par rejeu.

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

    Vous envoyez le hachage SHA256 du nonce avec votre requête de connexion, que Apple transmet dans la réponse sans la modifier. Firebase valide la réponse en hachant le nonce d'origine et en le comparant à la valeur transmise par Apple.

  2. Lancez le flux de connexion d'Apple, y compris dans votre requête, le hachage SHA256 de le nonce et la classe déléguée qui gérera la réponse d'Apple (voir l'étape suivante):

      - (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. Gérez la réponse d'Apple dans votre implémentation de ASAuthorizationControllerDelegate". Si la connexion a réussi, utilisez l'ID à partir de la réponse d'Apple avec le nonce non haché pour s'authentifier 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. Utilisez la chaîne de jeton obtenue et le nonce d'origine pour créer un objet Firebase Obtenez des identifiants et connectez-vous à Firebase.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  5. Le même schéma peut être utilisé avec Reauthenticate, qui peut être utilisé pour récupérer de nouveaux identifiants pour les opérations sensibles qui nécessitent une connexion récente.

    firebase::Future<firebase::auth::AuthResult> result =
        user->Reauthenticate(credential);
    
  6. Vous pouvez utiliser le même schéma pour associer un compte via Apple Sign-In. Toutefois, une erreur peut se produire lorsqu'un compte Firebase existant a déjà été associé au compte Apple que vous essayez d'associer. Dans ce cas, le prochain renvoie le statut kAuthErrorCredentialAlreadyInUse et AuthResult peuvent contenir une valeur credential Ces identifiants peuvent être utilisés pour vous connecter au compte associé à Apple via SignInAndRetrieveDataWithCredential sans avoir à générer un autre jeton et un autre nonce de connexion 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.
    }

Sur Android

Sur Android, authentifiez vos utilisateurs avec Firebase en intégrant l'authentification une connexion OAuth générique à votre application à l'aide du SDK Firebase pour effectuer la fin mettre fin au processus de connexion.

Pour gérer le flux de connexion avec le SDK Firebase, procédez comme suit:

  1. Construire une instance d'un FederatedOAuthProviderData configuré avec l'ID de fournisseur approprié pour Apple.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. Facultatif : spécifiez des champs d'application OAuth 2.0 supplémentaires en plus de ceux par défaut que vous souhaitez demander au fournisseur d'authentification.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. Facultatif:Si vous souhaitez afficher l'écran de connexion d'Apple dans une langue (autre qu'en anglais), définissez le paramètre locale. Consultez le Se connecter avec Apple Docs pour les paramètres régionaux pris en charge.

    // Localize to French.
    provider_data.custom_parameters["language"] = "fr";
    ```
    
  4. Une fois les données de votre fournisseur configurées, utilisez-les pour créer FederatedOAuthProvider.

    // Construct a FederatedOAuthProvider for use in Auth methods.
    firebase::auth::FederatedOAuthProvider provider(provider_data);
    
  5. Authentifiez-vous avec Firebase à l'aide de l'objet du fournisseur d'authentification. Notez que contrairement d'autres opérations FirebaseAuth, elle prendra le contrôle de votre UI une vue Web dans laquelle l'utilisateur peut saisir ses identifiants.

    Pour démarrer le flux de connexion, appelez signInWithProvider :

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

    Votre application peut ensuite attendre ou enregistrer un rappel sur le Future.

  6. Le même schéma peut être utilisé avec ReauthenticateWithProvider, qui peut être utilisé pour récupérer de nouveaux identifiants pour les opérations sensibles qui nécessitent connexion récente.

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

    Il est possible que votre application attende ou enregistre un rappel le l'avenir.

  7. Vous pouvez également utiliser LinkWithCredential() pour associer différents fournisseurs d'identité aux comptes existants.

    Notez qu'Apple vous demande d'obtenir le consentement explicite des utilisateurs avant de lier leurs comptes Apple à d'autres données.

    Par exemple, pour associer un compte Facebook au compte Firebase actuel, utilisez Le jeton d'accès obtenu lors de la connexion de l'utilisateur à Facebook:

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

Se connecter avec Apple Notes

Contrairement aux autres fournisseurs acceptés par Firebase Auth, Apple ne fournit pas d'URL de photo.

De plus, si l'utilisateur choisit de ne pas partager son adresse e-mail avec l'application, Apple fournit une adresse e-mail unique pour cet utilisateur (au format xyz@privaterelay.appleid.com), qu'il partage avec votre application. Si vous configuré le service de relais de messagerie privé, Apple transfère les e-mails envoyés l'adresse anonyme à la véritable adresse e-mail de l'utilisateur.

Apple ne partage des informations sur l'utilisateur (nom à afficher, par exemple) qu'avec les applications auxquelles lorsqu'un utilisateur se connecte pour la première fois. En règle générale, Firebase stocke le nom à afficher la première fois qu'un utilisateur se connecte avec Apple. Vous pouvez l'obtenir avec current_user().display_name(). Toutefois, si vous avez déjà utilisé Apple pour signer un à accéder à l'application sans utiliser Firebase, Apple ne fournira pas à Firebase le nom à afficher de l'utilisateur.

Étapes suivantes

Lorsqu'un utilisateur se connecte pour la première fois, un compte utilisateur est créé et associé aux identifiants (nom d'utilisateur et mot de passe, numéro de téléphone ou informations du fournisseur d'authentification) avec lesquels l'utilisateur s'est connecté. Ce nouveau compte est stocké sous de votre projet Firebase, et peuvent servir à identifier un utilisateur dans chaque application dans votre projet, quelle que soit la façon dont l'utilisateur se connecte.

Dans vos applications, vous pouvez obtenir les informations de profil de base de l'utilisateur à partir de l'objet firebase::auth::User. Voir Gérer les utilisateurs

Dans vos règles de sécurité Firebase Realtime Database et Cloud Storage, vous pouvez obtenir l'ID utilisateur unique de l'utilisateur connecté à partir de la variable d'authentification et l'utiliser pour contrôler les données auxquelles un utilisateur peut accéder.