Jak dodać logowanie przez Apple do React Native, nie tracąc przy tym zmysłów
Jeśli kiedykolwiek wdrażałeś aplikację mobilną z logowaniem przez Google lub media społecznościowe w App Store, prawdopodobnie spotkałeś się z surową zasadą recenzentów: jeśli dodajesz logowanie przez zewnętrznych dostawców, musisz również uwzględnić Sign In with Apple. W przeciwnym razie odrzucenie nastąpi szybciej, niż zakończy się kompilacja wersji release.
Zadanie wydaje się proste na pierwszy rzut oka. Ale gdy zaczniesz zagłębiać się w wywołania natywne, dziwactwa symulatorów i ekscentryczności API Apple, pojawia się cała masa pułapek. Zespół Invertase (ci sami ludzie, którzy stoją za React Native Firebase) stworzył bibliotekę o nazwie react-native-apple-authentication, która obsługuje to zarówno na iOS, jak i Android.

Co kryje się pod maską i dlaczego tego potrzebujesz
Biblioteka zapewnia pełny dostęp do mechanizmu uwierzytelniania Apple. Działa na czystym React Native od wersji 0.60, dobrze współpracuje z Expo (poprzez prebuild i konfigurację entitlements w app.json), obsługuje macOS, a nawet może uwierzytelniać użytkowników Androida przez przepływ przeglądarkowy.
Najlepsze jest to, że otrzymujesz gotowe definicje TypeScript i natywny komponent przycisku AppleButton. Projekt przycisku jest ściśle regulowany przez wytyczne Apple. Jeśli narysujesz go samodzielnie, recenzenci z radością odrzucą Twoją aplikację. Tutaj style i lokalizacja są pobierane bezpośrednio z systemu natywnego.
Jak działa podstawowy przepływ na iOS
Instalacja jest standardowa: zainstaluj pakiet przez yarn lub npm, a następnie uruchom pod install w folderze ios. Moduł obsługuje autolinking, więc nie będziesz musiał grzebać w AppDelegate.
Do obsługi przycisku i logiki logowania potrzebujesz tylko kilku importów:
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>
);
}
Pułapki, na które natrafia każdy początkujący
Autoryzacja Apple ma nieoczywiste dziwactwa, o których warto wiedzieć, zanim znajdziesz się w sytuacji debugowania do 3 w nocy.
Imię i e-mail przychodzą tylko raz
Apple jest zauroczony prywatnością. Przy pierwszym logowaniu użytkownik może wybrać ukrycie swojego prawdziwego e-maila lub jego udostępnienie. Dane profilu (fullName fullName i email email) są zwracane przez natywny framework dokładnie raz — podczas pierwszego udanego uwierzytelniania.
Przy kolejnych wywołaniach te pola wracają puste (null null). Jeśli nie zapisałeś od razu nazwy i e-maila do swojej bazy danych, nie możesz ich ponownie pobrać przez API klienta.
Aby zresetować stan testowy na iPhonie i ponownie otrzymać profil, musisz ręcznie przejść do ustawień systemowych: Ustawienia → [Twoje imię] → Hasło i bezpieczeństwo → Logowania Apple ID Настройки > Apple ID > Пароль и безопасность > Приложения, использующие Apple ID, usuń tam swoją testową aplikację i zaloguj się ponownie.
Przy okazji, repozytorium projektu wyraźnie wspomina o błędzie w samym API Apple: scopes muszą być przekazane w dokładnie określonej kolejności [FULL_NAME, EMAIL]. Jeśli je zamienisz, imię może zostać utracone już przy pierwszym żądaniu.
Symulatory i błąd 1000
Metoda currentUser getCredentialStateForUser weryfikuje autentyczność urządzenia. Na symulatorach iOS regularnie powoduje błąd 1000 com.apple.AuthenticationServices.AuthorizationError error 1000. Pełne testowanie łańcucha autoryzacji możliwe jest tylko na fizycznym urządzeniu.
Jeśli symulator całkowicie zawiesi się na tym błędzie, deweloperzy zalecają przejście na stronę zarządzania Apple ID, znalezienie listy powiązanych urządzeń i usunięcie symulatora z konta.


Wylogowanie to iluzja
Enums modułu zawierają operację wylogowania appleAuth.Operation.LOGOUT, ale w praktyce natywny SDK iOS nic z tym nie robi. Apple nie udostępnia sposobu na wymuszenie wylogowania na poziomie urządzenia. Wylogowanie po stronie klienta oznacza tylko usunięcie lokalnej sesji, zapisanych tokenów i wyczyszczenie stanu aplikacji.
Odbieranie dostępu
Użytkownicy mogą w dowolnym momencie przejść do ustawień iOS i cofnąć uprawnienia dla Twojej aplikacji do logowania. Aby zareagować na czas i odesłać użytkownika z powrotem do ekranu logowania, biblioteka udostępnia nasłuchiwacz zdarzeń:
useEffect(() => {
const unsubscribe = appleAuth.onCredentialRevoked(async () => {
// Токены больше не валидны, сбрасываем локальное состояние
console.warn('Доступ отозван пользователем в настройках Apple ID');
});
return () => unsubscribe();
}, []);
A co z Androidem
Wielu jest zaskoczonych, ale możesz również pozwolić użytkownikom Androida logować się przez Apple ID. Mechanika jest tam inna: zamiast natywnego frameworka, otwiera się chronione okno przeglądarki przez OAuth 2.0 Web Flow.
Biblioteka obsługuje tę rutynę przez moduł 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 на сервер
}
Na Androida musisz skonfigurować Service ID w Apple Developer Console i określić Redirect URL. Główna zasada: link przekierowania musi być identyczny znak po znaku z tym, co jest wpisane w konsoli dewelopera — bez parametrów zapytania.
Walidacja po stronie serwera
Nigdy nie ufaj слепо nonce user ID po stronie klienta. Klient otrzymuje identityToken identityToken (podpisany JWT). Na serwerze dekodujesz go, weryfikujesz podpis kluczami publicznymi Apple i sprawdzasz nonce nonce.
Moduł automatycznie oblicza skrót SHA256 przekazanego nonce nonce przed wysłaniem go do Apple (podobnie jak robi to Firebase Auth). Miej to na uwadze po stronie backendu: musisz porównywać wartość zhashowaną.
Jeśli Twoim celem jest szybkie spełnienie wymagań App Store Review lub danie użytkownikom wygodnego logowania jednym dotknięciem przez Face ID, biblioteka Invertase jest najbardziej niezawodnym wyborem w ekosystemie React Native. Oszczędza Ci pisania własnego natywnego mostka w Swift/Objective-C, elegancko obsługuje stylizację przycisków i jest konsekwentnie aktualizowana przez opiekunów. Zainstaluj ją, skonfiguruj certyfikaty w Apple Developer Console, ustaw handler — i Twój release jest gotowy do wysłania.
Powiązane projekty