Como Adicionar Login com Apple ao React Native Sem Enlouquecer
Se você já implantou um aplicativo móvel com login do Google ou redes sociais na App Store, provavelmente já encontrou a regra rígida dos revisores: se você adicionar login de terceiros, também deve incluir o Login com Apple. Caso contrário, a rejeição vem mais rápido do que um build de release consegue terminar de compilar.
A tarefa parece simples à primeira vista. Mas assim que você começa a se aprofundar em chamadas nativas, peculiaridades do simulador e excentricidades da API da Apple, uma série de armadilhas aparecem. A equipe do Invertase (as mesmas pessoas por trás do React Native Firebase) criou uma biblioteca chamada react-native-apple-authentication que lida com isso tanto para iOS quanto para Android.

O que está sob o capô e por que você precisa disso
A biblioteca fornece acesso completo ao mecanismo de autenticação da Apple. Funciona no React Native vanilla a partir da versão 0.60, é compatível com Expo (via prebuild e configuração de entitlements em app.json), suporta macOS e pode até autenticar usuários Android via fluxo de navegador.
O melhor é ter as definições TypeScript prontas para uso e o componente de botão nativo já preparado AppleButton. O design do botão é estritamente regulamentado pelas diretrizes da Apple. Se você desenhá-lo sozinho, os revisores vão rejeitar seu aplicativo com prazer. Aqui, os estilos e a localização são extraídos diretamente do sistema nativo.
Como funciona o fluxo básico no iOS
A instalação é padrão: instale o pacote via yarn ou npm, depois execute pod install na pasta ios. O módulo suporta autolinking, então você não precisará mexer no AppDelegate.
Para o botão e a lógica de login, você só precisa de alguns 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>
);
}
Armadilhas nas quais todos os iniciantes tropeçam
A autorização da Apple tem peculiaridades não óbvias que vale a pena conhecer antes de se ver depurando até as 3 da manhã.
Nome e email só aparecem uma vez
A Apple é obcecada por privacidade. No primeiro login, o usuário pode escolher ocultar seu email real ou compartilhá-lo. Os dados do perfil (fullName fullName e email email) são retornados pelo framework nativo exatamente uma vez — durante a primeira autorização bem-sucedida.
Em chamadas subsequentes, esses campos voltam vazios (null null). Se você não salvou o nome e email no seu banco de dados imediatamente, não pode recuperá-los novamente através da API do cliente.
Para redefinir o estado de teste em um iPhone e receber o perfil novamente, você precisa ir manualmente para as configurações do sistema: Ajustes → [Seu Nome] → Senha e Segurança → Logins do Apple ID Настройки > Apple ID > Пароль и безопасность > Приложения, использующие Apple ID, remover seu aplicativo de teste lá e fazer login novamente.
A propósito, o repositório do projeto observa especificamente um bug na própria API da Apple: os scopes devem ser passados exatamente na ordem [FULL_NAME, EMAIL]. Se você trocar a ordem, o nome pode ser perdido já na primeira requisição.
Simuladores e erro 1000
O método currentUser getCredentialStateForUser verifica a autenticidade do dispositivo. Nos simuladores iOS, ele falha regularmente com o erro 1000 com.apple.AuthenticationServices.AuthorizationError error 1000. Você só pode testar completamente a cadeia de autorização em um dispositivo físico.
Se o simulador estiver completamente travado nesse erro, os desenvolvedores recomendam ir ao site de gerenciamento de ID Apple, encontrar a lista de dispositivos associados e remover o simulador da sua conta.


Logout é uma ilusão
Os enums do módulo incluem uma operação de logout appleAuth.Operation.LOGOUT, mas na prática o SDK nativo iOS não faz nada com ela. A Apple não fornece uma forma de forçar logout do sistema no nível do dispositivo. O logout do lado do cliente significa apenas apagar sua sessão local, tokens salvos e limpar o estado do aplicativo.
Revogando acesso
Os usuários podem a qualquer momento ir para os ajustes do iOS e revogar a permissão do seu aplicativo para fazer login. Para reagir a tempo e devolver o usuário à tela de login, a biblioteca fornece um listener de eventos:
useEffect(() => {
const unsubscribe = appleAuth.onCredentialRevoked(async () => {
// Токены больше не валидны, сбрасываем локальное состояние
console.warn('Доступ отозван пользователем в настройках Apple ID');
});
return () => unsubscribe();
}, []);
E o Android
Muitos ficam surpresos, mas você também pode permitir que usuários Android façam login com Apple ID. A mecânica é diferente lá: em vez de um framework nativo, uma janela protegida do navegador abre via OAuth 2.0 Web Flow.
A biblioteca trata da rotina através do 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, você precisará configurar um Service ID no Apple Developer Console e especificar uma Redirect URL. A regra principal: o link de redirecionamento deve corresponder caractere por caractere ao que está inserido no console do desenvolvedor — sem parâmetros de query permitidos.
Validação no servidor
Nunca confie no nonce user ID do lado do cliente cegamente. O cliente recebe identityToken identityToken (um JWT assinado). No servidor, você decodifica, verifica a assinatura com as chaves públicas da Apple e verifica o nonce nonce.
O módulo calcula automaticamente o hash SHA256 do nonce passado nonce antes de enviá-lo à Apple (similar ao que o Firebase Auth faz). Tenha isso em mente no backend: você precisa comparar o valor com hash.
Se seu objetivo é satisfazer rapidamente os requisitos de revisão da App Store ou oferecer aos usuários um login conveniente com um toque via Face ID, a biblioteca da Invertase é a escolha mais confiável no ecossistema React Native. Ela evita que você escreva sua própria bridge nativa em Swift/Objective-C, trata elegantemente o estilo do botão e é consistentemente atualizada pelos mantenedores. Instale, configure os certificados no Apple Developer Console, configure o handler — e seu release está pronto para enviar.
Projetos relacionados