Come aggiungere Apple Sign-In a React Native senza perdere la testa
Se hai mai pubblicato un'app mobile con login Google o social sull'App Store, probabilmente hai incontrato la regola ferrea dei revisori: se aggiungi un accesso di terze parti, devi includere anche Sign In with Apple. Altrimenti, il rifiuto arriva più velocemente di quanto un release build possa finire di compilare.
Il compito sembra semplice all'inizio. Ma una volta che inizi a scavare nelle chiamate native, nelle bizzarrie dei simulatori e nelle eccentricità delle API di Apple, emergono una serie di insidie. Il team di Invertase (gli stessi creatori di React Native Firebase) ha sviluppato una libreria chiamata react-native-apple-authentication che gestisce questo sia per iOS che per Android.

Cosa c'è sotto il cofano e perché ti serve
La libreria fornisce accesso completo al meccanismo di autenticazione di Apple. Funziona su React Native vanilla dalla versione 0.60, è compatibile con Expo (tramite prebuild e configurazione degli entitlements in app.json), supporta macOS, e può persino autenticare utenti Android tramite flusso browser.
La parte migliore sono le definizioni TypeScript pronte all'uso e il componente pulsante nativo già pronto AppleButton. Il design del pulsante è strettamente regolamentato dalle linee guida di Apple. Se lo disegni tu stesso, i revisori saranno felici di rifiutare la tua app. Qui, stili e localizzazione vengono prelevati direttamente dal sistema nativo.
Come funziona il flusso base su iOS
L'installazione è standard: installa il pacchetto tramite yarn o npm, poi esegui pod install nella cartella ios. Il modulo supporta l'autolinking, quindi non dovrai scavare in AppDelegate.
Per il pulsante e la logica di login, ti servono solo un paio di importazioni:
import React from 'react';
import { View } from 'react-native';
import { AppleButton, appleAuth } from '@invertase/react-native-apple-authentication';
export function LoginScreen() {
async function handleAppleLogin() {
// Запускаем нативный запрос авторизации
const authResponse = await appleAuth.performRequest({
requestedOperation: appleAuth.Operation.LOGIN,
// Порядок скоупов имеет значение
requestedScopes: [appleAuth.Scope.FULL_NAME, appleAuth.Scope.EMAIL],
});
// Проверяем статус пользователя
const credentialState = await appleAuth.getCredentialStateForUser(authResponse.user);
if (credentialState === appleAuth.State.AUTHORIZED) {
// Пользователь подтвержден, отправляем токены на бэкенд
console.log('User ID:', authResponse.user);
console.log('Identity Token:', authResponse.identityToken);
}
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<AppleButton
buttonStyle={AppleButton.Style.BLACK}
buttonType={AppleButton.Type.SIGN_IN}
style={{ width: 200, height: 45 }}
onPress={handleAppleLogin}
/>
</View>
);
}
Le insidie su cui inciampano tutti i principianti
L'autorizzazione di Apple ha delle particolarità non ovvie che vale la pena conoscere prima di ritrovarti a fare debug fino alle 3 di notte.
Nome ed email arrivano solo una volta
Apple è ossessionata dalla privacy. Al primo accesso, l'utente può scegliere di nascondere la sua email reale o condividerla. I dati del profilo (fullName fullName ed email email) vengono restituiti dal framework nativo esattamente una volta — durante la primissima autorizzazione riuscita.
nelle chiamate successive, questi campi tornano vuoti (null null). Se non hai salvato il nome e l'email nel tuo database subito, non puoi recuperarli più attraverso l'API client.
Per resettare lo stato di test su un iPhone e ricevere di nuovo il profilo, devi andare manualmente nelle impostazioni di sistema: Impostazioni → [Il tuo nome] → Password e sicurezza → Accessi Apple ID Настройки > Apple ID > Пароль и безопасность > Приложения, использующие Apple ID, rimuovere l'app di test lì, e accedere di nuovo.
A proposito, il repo del progetto segnala specificamente un bug nell'API stessa di Apple: gli scope devono essere passati esattamente nell'ordine [FULL_NAME, EMAIL]. Se li inverti, il nome potrebbe andare perso già alla prima richiesta.
Simulatori ed errore 1000
Il metodo currentUser getCredentialStateForUser verifica l'autenticità del dispositivo. Sui simulatori iOS, va regolarmente in crash con errore 1000 com.apple.AuthenticationServices.AuthorizationError error 1000. Puoi testare completamente la catena di autorizzazione solo su un dispositivo fisico.
Se il simulatore è completamente bloccato su questo errore, gli sviluppatori consigliano di andare sul sito web di gestione dell'Apple ID, trovare l'elenco dei dispositivi associati, e rimuovere il simulatore dal tuo account.


Il logout è un'illusione
Gli enum del modulo includono un'operazione di logout appleAuth.Operation.LOGOUT, ma in pratica l'SDK nativo iOS non fa nulla con essa. Apple non fornisce un modo per forzare il logout a livello di sistema sul dispositivo. Il logout lato client significa solo cancellare la tua sessione locale, i token salvati e pulire lo stato dell'app.
Revoca dell'accesso
Gli utenti possono in qualsiasi momento andare nelle impostazioni iOS e revocare il permesso per la tua app di accedere. Per reagire in tempo e riportare l'utente alla schermata di login, la libreria fornisce un listener di eventi:
useEffect(() => {
const unsubscribe = appleAuth.onCredentialRevoked(async () => {
// Токены больше не валидны, сбрасываем локальное состояние
console.warn('Доступ отозван пользователем в настройках Apple ID');
});
return () => unsubscribe();
}, []);
E per Android?
Molti sono sorpresi, ma puoi anche far accedere gli utenti Android con Apple ID. La meccanica è diversa lì: invece di un framework nativo, si apre una finestra del browser protetta tramite OAuth 2.0 Web Flow.
La libreria gestisce la routine attraverso il modulo ASWebAuthenticationSession appleAuthAndroid:
import { appleAuthAndroid } from '@invertase/react-native-apple-authentication';
import 'react-native-get-random-values';
import { v4 as uuid } from 'uuid';
async function handleAndroidAppleLogin() {
const rawNonce = uuid();
const state = uuid();
appleAuthAndroid.configure({
clientId: 'com.example.client-android', // Service ID из консоли Apple Developer
redirectUri: 'https://example.com/auth/callback',
responseType: appleAuthAndroid.ResponseType.ALL,
scope: appleAuthAndroid.Scope.ALL,
nonce: rawNonce,
state,
});
const response = await appleAuthAndroid.signIn();
// Отправляем response.code и response.id_token на сервер
}
Per Android, dovrai configurare un Service ID in Apple Developer Console e specificare un Redirect URL. La regola principale: il link di redirect deve corrispondere carattere per carattere a ciò che è inserito nella console di sviluppo — nessun parametro query consentito.
Validazione lato server
Non fidarti mai ciecamente del nonce lato client user ID. Il client riceve identityToken identityToken (un JWT firmato). Sul server, lo decodifichi, verifichi la firma con le chiavi pubbliche di Apple, e controlli il nonce nonce.
Il modulo calcola automaticamente l'hash SHA256 del nonce passato nonce prima di inviarlo ad Apple (in modo simile a come fa Firebase Auth). Tienilo a mente sul backend: devi confrontare il valore hashed.
Se il tuo obiettivo è soddisfare rapidamente i requisiti di App Store Review o dare agli utenti un comodo accesso con un tap tramite Face ID, la libreria di Invertase è la scelta più affidabile nell'ecosistema React Native. Ti risparmia di scrivere il tuo bridge nativo in Swift/Objective-C, gestisce elegantemente lo stile del pulsante, ed è costantemente aggiornata dai maintainer. Installala, configura i certificati in Apple Developer Console, imposta l'handler — e la tua release è pronta per essere inviata.
Progetti correlati