Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Accesso degli utenti con Apple su iOS

Questo documento mostra come utilizzare Identity Platform per aggiungere Accedi con Apple all'app iOS.

Prima di iniziare

Configurazione dell'app con Apple

Sul sito per sviluppatori Apple:

  1. Attiva la funzionalità Accedi con Apple per la tua app.

  2. Se utilizzi Identity Platform per inviare email ai tuoi utenti, configura il progetto con il servizio di inoltro privato di Apple utilizzando il seguente indirizzo email:

    noreply@project-id.firebaseapp.com
    

    Puoi anche utilizzare un modello di email personalizzato, se disponibile nella tua app.

Conformità ai requisiti relativi ai dati anonimi di Apple

Apple offre agli utenti la possibilità di rendere anonimi i propri dati, incluso il loro indirizzo email. Apple assegna agli utenti che selezionano questa opzione un indirizzo email offuscato con il dominio privaterelay.appleid.com.

L'app deve essere conforme a eventuali norme o termini per sviluppatori applicabili di Apple relativi agli ID Apple anonimizzati. Questo include l'ottenimento del consenso degli utenti prima di associare qualsiasi informazione che consenta l'identificazione personale (PII) a un ID Apple anonimo. Le azioni che riguardano PII includono, a titolo esemplificativo:

  • Collegamento di un indirizzo email a un ID Apple anonimo o viceversa.
  • Collegamento di un numero di telefono a un ID Apple anonimo o viceversa
  • Collegamento di una credenziale social non anonima, ad esempio Facebook o Google, a un ID Apple anonimo o viceversa.

Per ulteriori informazioni, consulta il Contratto di licenza del programma per sviluppatori Apple per il tuo account sviluppatore Apple.

Configurazione di Apple come provider

Per configurare Apple come provider di identità:

  1. Vai alla pagina Provider di Identity Platform nella console Google Cloud.

    Vai alla pagina Provider di identità

  2. Fai clic su Aggiungi un fornitore.

  3. Seleziona Apple dall'elenco.

  4. In Piattaforma, seleziona iOS.

  5. Inserisci l'ID bolla dell'app.

  6. Registra i domini dell'app facendo clic su Aggiungi dominio in Domini autorizzati. A scopo di sviluppo, localhost è già attivato per impostazione predefinita.

  7. In Configura la tua applicazione, fai clic su iOS. Copia lo snippet nel codice della tua app per inizializzare l'SDK client di Identity Platform.

  8. Fai clic su Salva.

Accesso degli utenti con l'SDK client

  1. Consenti all'utente di accedere e ottenere un token ID utilizzando il framework Servizi di autenticazione di Apple.

  2. Genera una stringa casuale, nota come nonce, chiamando SecRandomCopyBytes(_:_:_:).

    Il nonce viene utilizzato per impedire gli attacchi di ripetizione. Includi l'hash SHA-256 del nonce nella richiesta di autenticazione e Apple lo restituisce, non modificato, nella risposta. Identity Platform convalida quindi la risposta confrontando l'hash originale con il valore restituito da Apple.

  3. Avvia il flusso di accesso di Apple, incluso l'hash SHA-256 del nonce che hai creato nel passaggio precedente, e una classe del delegato per gestire la risposta di Apple:

    Swift

    import CryptoKit
    
    // Unhashed nonce.
    fileprivate var currentNonce: String?
    
    @available(iOS 13, *)
    func startSignInWithAppleFlow() {
      let nonce = randomNonceString()
      currentNonce = nonce
      let appleIDProvider = ASAuthorizationAppleIDProvider()
      let request = appleIDProvider.createRequest()
      request.requestedScopes = [.fullName, .email]
      request.nonce = sha256(nonce)
    
      let authorizationController = ASAuthorizationController(authorizationRequests: [request])
      authorizationController.delegate = self
      authorizationController.presentationContextProvider = self
      authorizationController.performRequests()
    }
    
    @available(iOS 13, *)
    private func sha256(_ input: String) -> String {
      let inputData = Data(input.utf8)
      let hashedData = SHA256.hash(data: inputData)
      let hashString = hashedData.compactMap {
        return String(format: "%02x", $0)
      }.joined()
    
      return hashString
    }
    

    Objective-C

    @import CommonCrypto;
    
    - (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;
    }
    
  4. Gestisci la risposta di Apple nell'implementazione di ASAuthorizationControllerDelegate. Se l'accesso va a buon fine, utilizza il token ID della risposta di Apple con il nonce sottoposto ad hashing per l'autenticazione con Identity Platform:

    Swift

    @available(iOS 13.0, *)
    extension MainViewController: ASAuthorizationControllerDelegate {
    
      func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
          guard let nonce = currentNonce else {
            fatalError("Invalid state: A login callback was received, but no login request was sent.")
          }
          guard let appleIDToken = appleIDCredential.identityToken else {
            print("Unable to fetch identity token")
            return
          }
          guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
            print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
            return
          }
          // Initialize a Firebase credential.
          let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                    IDToken: idTokenString,
                                                    rawNonce: nonce)
          // Sign in with Firebase.
          Auth.auth().signIn(with: credential) { (authResult, error) in
            if error {
              // Error. If error.code == .MissingOrInvalidNonce, make sure
              // you're sending the SHA256-hashed nonce as a hex string with
              // your request to Apple.
              print(error.localizedDescription)
              return
            }
            // User is signed in to Firebase with Apple.
            // ...
          }
        }
      }
    
      func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        // Handle error.
        print("Sign in with Apple errored: \(error)")
      }
    }
    

    Objective-C

    - (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);
        }
        // Initialize a Firebase credential.
        FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com"
                                                                            IDToken:idToken
                                                                           rawNonce:rawNonce];
        // Sign in with Firebase.
        [[FIRAuth auth] signInWithCredential:credential
                                  completion:^(FIRAuthDataResult * _Nullable authResult,
                                               NSError * _Nullable error) {
          if (error != nil) {
            // Error. If error.code == FIRAuthErrorCodeMissingOrInvalidNonce,
            // make sure you're sending the SHA256-hashed nonce as a hex string
            // with your request to Apple.
            return;
          }
          // Sign-in succeeded!
        }];
      }
    }
    
    - (void)authorizationController:(ASAuthorizationController *)controller
               didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
      NSLog(@"Sign in with Apple errored: %@", error);
    }
    

A differenza di molti altri provider di identità, Apple non fornisce l'URL di una foto.

Se un utente sceglie di non condividere la propria email reale con la tua app, Apple esegue il provisioning di un indirizzo email univoco da condividere con quell'utente. Questa email ha il formato xyz@privaterelay.appleid.com. Se hai configurato il servizio di inoltro email privato, Apple inoltra le email inviate all'indirizzo anonimo all'indirizzo email reale dell'utente.

Apple condivide le informazioni relative agli utenti, ad esempio i nomi visualizzati, con le app solo al primo accesso degli utenti. Nella maggior parte dei casi, Identity Platform archivia questi dati, consentendoti di recuperarli utilizzando firebase.auth().currentUser.displayName durante le sessioni future. Tuttavia, se hai consentito agli utenti di accedere alla tua app utilizzando Apple prima dell'integrazione con Identity Platform, le informazioni utente non sono disponibili.

Passaggi successivi