Przejdź do głównej zawartości

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ć

  1. Na ekranie logowania kliknij okrągły przycisk z jabłkiem (obok przycisku Google).
  2. Apple zapyta, czy chcesz udostępnić swój adres e-mail, czy go ukryć.
  3. 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

  1. App ID aplikacji iOS (dev.workers.dtmsoftwares.dmt-cms.twa) — włącz capability Sign in with Apple.
  2. Services ID — osobny identyfikator dla przepływu webowego. Jego wartość trafia do APPLE_CLIENT_ID.
  3. 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 przyjmuje localhost — lokalnie testuje się przez tunel HTTPS.
  4. 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

MiejsceCo robi
lib/auth.tssocialProviders.applerejestruje dostawcę
lib/auth.tstrustedOriginsdopuszcza https://appleid.apple.com, bo callback przychodzi jako POST z domeny Apple (response_mode=form_post)
lib/auth.tsaccountLinking.trustedProviderspozwala dołączyć Apple do konta o potwierdzonym adresie
lib/social-providers.tsjedno źródło listy dostawców dla UI i dla odczytu z bazy
capacitor.config.tsallowNavigationdopuszcza nawigację na appleid.apple.com
components/forms/userProfile/components/LinkSocialAccounts.tsxprzyciski „Połącz konto …" w profilu
scripts/generate-apple-client-secret.mjsmintuje 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ść.