Logowanie przez Apple
Sign in with Apple jako druga — obok Google — opcja logowania społecznościowego
na stronach /auth/login i /auth/register. Apple wymaga tej opcji od każdej
aplikacji w App Store, która oferuje logowanie innym dostawcą społecznościowym,
więc bez niej aplikacja mobilna AcePark nie przejdzie recenzji.
👤 Instrukcja dla klienta
Jak się zalogować
- Na ekranie logowania kliknij okrągły przycisk z jabłkiem (obok przycisku Google).
- Apple zapyta, czy chcesz udostępnić swój adres e-mail, czy go ukryć.
- Po potwierdzeniu wracasz do AcePark już zalogowany.
Ukryty adres e-mail
Jeśli wybierzesz „Ukryj mój adres e-mail”, Apple utworzy adres przekierowujący
w domenie @privaterelay.appleid.com. Konto w AcePark powstanie na tym
adresie, a nie na Twoim prawdziwym — potwierdzenia rezerwacji i tak dotrą do
Twojej skrzynki, bo Apple je przekazuje dalej.
Ma to jednak dwie praktyczne konsekwencje:
- Recepcja nie znajdzie Cię w systemie po Twoim zwykłym adresie e-mail.
- Jeśli wcześniej miałeś konto na zwykłym adresie, logowanie przez Apple z ukrytym adresem utworzy drugie, osobne konto.
Dlatego przy pierwszym logowaniu warto wybrać „Udostępnij mój adres”.
Dołączenie Apple do konta, które już masz
W Profilu → Bezpieczeństwo → Połączone konta znajdziesz przyciski „Połącz konto Google" i „Połącz konto Apple" — pokazujemy tylko te, których jeszcze nie masz. Linkowanie z wnętrza zalogowanej sesji jest bezpieczne: skoro jesteś już w środku, nie musimy potwierdzać adresu e-mail w żaden inny sposób.
Mam już konto na ten adres
Jeśli adres z Apple ma już profil w AcePark, ale nigdy nie potwierdziliśmy tej skrzynki, zobaczysz komunikat „To konto już u nas istnieje”. Zaloguj się wtedy numerem telefonu lub hasłem — po ustawieniu hasła z linku, który wyślemy mailem, adres staje się potwierdzony i Apple da się do niego dołączyć.
🛠 Dokumentacja techniczna
Przepływ
Apple jest zwykłym dostawcą OAuth w Better Auth — nie ma tu żadnego natywnego SDK ani wtyczki Capacitora.
W aplikacji mobilnej cały ten przepływ dzieje się wewnątrz
ASWebAuthenticationSession otwartego przez CustomWebViewController.swift,
tak samo jak logowanie Google, i kończy się przekierowaniem na
acepark://auth-complete?code=… przez /api/auth/mobile-handoff.
Konfiguracja w portalu Apple Developer
- App ID aplikacji iOS (
dev.workers.dtmsoftwares.dmt-cms.twa) — włącz capability Sign in with Apple. - Services ID — osobny identyfikator dla przepływu webowego. Jego wartość
trafia do
APPLE_CLIENT_ID. - W Services ID skonfiguruj:
- Domains:
klient.acepark.pl(oraz każda inna domena workera), - Return URLs:
https://klient.acepark.pl/api/auth/callback/apple. Apple nie przyjmujelocalhost— lokalnie testuje się przez tunel HTTPS.
- Domains:
- Key typu Sign in with Apple — pobierz plik
.p8(do pobrania tylko raz) i zanotuj Key ID oraz Team ID.
Sekret klienta
Apple nie wydaje stałego sekretu: APPLE_CLIENT_SECRET to JWT podpisany
algorytmem ES256 kluczem .p8, z iss = Team ID, sub = Services ID,
aud = https://appleid.apple.com i maksymalnie sześciomiesięcznym
czasem życia. Po wygaśnięciu logowanie zwraca invalid_client.
Do wygenerowania służy scripts/generate-apple-client-secret.mjs:
node scripts/generate-apple-client-secret.mjs \
--team-id ABCDE12345 \
--key-id XYZ9876543 \
--client-id pl.acepark.signin \
--key ./AuthKey_XYZ9876543.p8
Skrypt wypisuje JWT na stdout, a datę wygaśnięcia na stderr. Wynik zapisuje się jako secret workera:
wrangler secret put APPLE_CLIENT_SECRET
Plik .p8 trzymaj poza repozytorium — Apple pozwala pobrać go tylko raz, a kto
go ma, może wystawiać sekrety w imieniu aplikacji. Termin odnowienia sekretu
warto zapisać w kalendarzu: nie ma po nim żadnego ostrzeżenia poza padającym
logowaniem.
Konfiguracja w kodzie
| Miejsce | Co robi |
|---|---|
lib/auth.ts → socialProviders.apple | rejestruje dostawcę |
lib/auth.ts → trustedOrigins | dopuszcza https://appleid.apple.com, bo callback przychodzi jako POST z domeny Apple (response_mode=form_post) |
lib/auth.ts → accountLinking.trustedProviders | pozwala dołączyć Apple do konta o potwierdzonym adresie |
lib/social-providers.ts | jedno źródło listy dostawców dla UI i dla odczytu z bazy |
capacitor.config.ts → allowNavigation | dopuszcza nawigację na appleid.apple.com |
components/forms/userProfile/components/LinkSocialAccounts.tsx | przyciski „Połącz konto …" w profilu |
scripts/generate-apple-client-secret.mjs | mintuje APPLE_CLIENT_SECRET |
Imię i nazwisko tylko raz
Apple przekazuje user.name wyłącznie przy pierwszej autoryzacji, w polu
user formularza POST. Better Auth zapisuje je wtedy w rekordzie użytkownika.
Przy kolejnych logowaniach id_token zawiera już tylko sub i email, więc
skasowanie konta w AcePark bez cofnięcia zgody w ustawieniach Apple ID sprawi,
że nowe konto powstanie bez imienia i nazwiska.
Który przycisk widzi klient
getUserAuthProviders (lib/actions/users-db.ts) zwraca listę
socialProviders konta. Ekran „To konto loguje się przez …”
(app/auth/login/social-account-notice.tsx) renderuje przycisk dla każdego
dostawcy z tej listy, więc konto założone przez Apple nie dostaje przycisku
Google, którym nie dałoby się do niego wejść.