Cómo añadir Apple Sign-In a React Native sin perder la cabeza
Si alguna vez has desplegado una app móvil con login de Google o redes sociales en la App Store, probablemente te has encontrado con la regla estricta de los revisores: si añades inicio de sesión de terceros, también debes incluir Iniciar sesión con Apple. De lo contrario, el rechazo llega más rápido de lo que termina de compilar un release build.
La tarea parece sencilla al principio. Pero una vez que empiezas a profundizar en llamadas nativas, peculiaridades del simulador y las excentricidades de la API de Apple, surgen un sinfín de trampas. El equipo de Invertase (las mismas personas detrás de React Native Firebase) construyó una librería llamada react-native-apple-authentication que maneja esto tanto para iOS como para Android.

Qué hay debajo del capó y por qué lo necesitas
La librería proporciona acceso completo al mecanismo de autenticación de Apple. Funciona en React Native vanilla desde la versión 0.60, se lleva bien con Expo (vía prebuild y configuración de entitlements en app.json), soporta macOS, y puede autenticar usuarios de Android mediante browser flow.
Lo mejor son las definiciones TypeScript listas para usar y el componente de botón nativo AppleButton. El diseño del botón está estrictamente regulado por las guías de Apple. Si lo dibujas tú mismo, los revisores rechazarán felizmente tu app. Aquí, los estilos y la localización se obtienen directamente del sistema nativo.
Cómo funciona el flujo básico en iOS
La instalación es estándar: instala el paquete vía yarn o npm, luego ejecuta pod install en la carpeta ios. El módulo soporta autolinking, así que no necesitarás meterte en AppDelegate.
Para el botón y la lógica de login, solo necesitas un par de imports:
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>
);
}
Trampas en las que tropiezan todos los principiantes
La autorización de Apple tiene peculiaridades poco obvias que vale la pena conocer antes de encontrarte depurando hasta las 3 AM.
El nombre y el correo solo llegan una vez
Apple está obsesionada con la privacidad. En el primer inicio de sesión, el usuario puede elegir ocultar su correo real o compartirlo. Los datos del perfil (fullName fullName y email email) son devueltos por el framework nativo exactamente una vez — durante la primera autorización exitosa.
En llamadas posteriores, estos campos vuelven vacíos (null null). Si no guardaste el nombre y correo en tu base de datos de inmediato, no puedes recuperarlos de nuevo a través de la API del cliente.
Para reiniciar el estado de prueba en un iPhone y recibir el perfil de nuevo, tienes que ir manualmente a Ajustes → [Tu Nombre] → Contraseña y Seguridad → Inicios de sesión de Apple ID Настройки > Apple ID > Пароль и безопасность > Приложения, использующие Apple ID, eliminar tu app de prueba allí, e iniciar sesión de nuevo.
Por cierto, el repo del proyecto específicamente señala un bug en la propia API de Apple: los scopes deben pasarse en el orden exacto [FULL_NAME, EMAIL]. Si los intercambias, el nombre puede perderse justo en la primera solicitud.
Simuladores y error 1000
El método currentUser getCredentialStateForUser verifica la autenticidad del dispositivo. En simuladores de iOS, regularmente falla con error 1000 com.apple.AuthenticationServices.AuthorizationError error 1000. Solo puedes probar completamente la cadena de autorización en un dispositivo físico.
Si el simulador se queda completamente atascado con este error, los desarrolladores recomiendan ir al sitio web de gestión de Apple ID, encontrar la lista de dispositivos asociados, y eliminar el simulador de tu cuenta.


El logout es una ilusión
Los enums del módulo incluyen una operación de logout appleAuth.Operation.LOGOUT, pero en la práctica el SDK nativo de iOS no hace nada con ella. Apple no proporciona una forma de forzar el logout desde el sistema a nivel de dispositivo. El logout del lado del cliente solo significa borrar tu sesión local, tokens guardados, y limpiar el estado de la app.
Revocar acceso
Los usuarios pueden en cualquier momento ir a los ajustes de iOS y revocar el permiso de tu app para iniciar sesión. Para reaccionar a tiempo y devolver al usuario a la pantalla de login, la librería proporciona un event listener:
useEffect(() => {
const unsubscribe = appleAuth.onCredentialRevoked(async () => {
// Токены больше не валидны, сбрасываем локальное состояние
console.warn('Доступ отозван пользователем в настройках Apple ID');
});
return () => unsubscribe();
}, []);
¿Y con Android?
Muchos se sorprenden, pero también puedes dejar que usuarios de Android inicien sesión con Apple ID. La mecánica es diferente allí: en lugar de un framework nativo, se abre una ventana de navegador protegida mediante OAuth 2.0 Web Flow.
La librería maneja la rutina a través del módulo 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 на сервер
}
Para Android, necesitarás configurar un Service ID en Apple Developer Console y especificar una Redirect URL. La regla principal: el enlace de redirect debe coincidir carácter por carácter con lo que está introducido en la consola de desarrollo — no se permiten parámetros de consulta.
Validación del lado del servidor
Nunca confíes ciegamente en el nonce del lado del cliente user ID. El cliente recibe identityToken identityToken (un JWT firmado). En el servidor, lo decodificas, verificas la firma con las claves públicas de Apple, y compruebas el nonce nonce.
El módulo calcula automáticamente el hash SHA256 del nonce pasado nonce antes de enviarlo a Apple (de forma similar a como lo hace Firebase Auth). Ten esto en cuenta en el backend: necesitas comparar el valor con hash.
Si tu objetivo es satisfacer rápidamente los requisitos de App Store Review o dar a los usuarios un login conveniente de un toque vía Face ID, la librería de Invertase es la opción más confiable en el ecosistema React Native. Te ahorra escribir tu propio bridge nativo en Swift/Objective-C, maneja elegantemente el estilo del botón, y es actualizada consistentemente por los mantenedores. Instálala, configura los certificados en Apple Developer Console, configura el handler — y tu release está lista para enviar.
Proyectos relacionados