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
Creare un'app per iOS che utilizzi Identity Platform.
Partecipa all'Apple Developer Program.
Configurazione dell'app con Apple
Sul sito per sviluppatori Apple:
Attiva la funzionalità Accedi con Apple per la tua app.
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à:
Vai alla pagina Provider di Identity Platform nella console Google Cloud.
Fai clic su Aggiungi un fornitore.
Seleziona Apple dall'elenco.
In Piattaforma, seleziona iOS.
Inserisci l'ID bolla dell'app.
Registra i domini dell'app facendo clic su Aggiungi dominio in Domini autorizzati. A scopo di sviluppo,
localhost
è già attivato per impostazione predefinita.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.
Fai clic su Salva.
Accesso degli utenti con l'SDK client
Consenti all'utente di accedere e ottenere un token ID utilizzando il framework Servizi di autenticazione di Apple.
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.
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; }
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
- Scopri di più sugli utenti di Identity Platform.
- Accesso degli utenti con altri provider di identità.