W tym dokumencie opisano najlepsze praktyki korzystania z przekierowań logowania w przeglądarkach, które blokują pliki cookie innych firm. Aby funkcja signInWithRedirect()
działała zgodnie z oczekiwaniami w środowiskach produkcyjnych i we wszystkich przeglądarkach, należy zastosować się do jednej z wymienionych tutaj opcji.
Przegląd
Aby zapewnić bezproblemowy przebieg funkcji signInWithRedirect()
dla Ciebie i Twoich użytkowników, pakiet SDK JavaScript do uwierzytelniania Firebase korzysta z ramki iframe pochodzącej z różnych źródeł, która łączy się z domeną Firebase Hosting Twojej aplikacji. Jednak ten mechanizm nie działa w przeglądarkach, które blokują dostęp do pamięci masowej stronom trzecim.
Ponieważ proszenie użytkowników o wyłączenie funkcji partycjonowania pamięci w przeglądarce rzadko wchodzi w grę, zamiast tego należy zastosować w aplikacji jedną z następujących opcji konfiguracji, w zależności od specyfiki przypadku użycia.
- Jeśli hostujesz swoją aplikację za pomocą Firebase Hosting w subdomenie
firebaseapp.com
, ten problem nie dotyczy Ciebie i nie jest konieczne żadne działanie. - Jeśli hostujesz swoją aplikację za pomocą Firebase Hosting w domenie niestandardowej lub subdomenie
web.app
, użyj Opcji 1 . - Jeśli hostujesz aplikację w usłudze innej niż Firebase, użyj Opcji 2 , Opcji 3 , Opcji 4 lub Opcji 5 .
Opcja 1: Zaktualizuj konfigurację Firebase, aby używać domeny niestandardowej jako domeny authDomain
Jeśli hostujesz swoją aplikację w Firebase Hosting przy użyciu domeny niestandardowej, możesz skonfigurować pakiet SDK Firebase tak, aby używał Twojej domeny niestandardowej jako domeny authDomain
. Dzięki temu Twoja aplikacja i element iframe uwierzytelniania korzystają z tej samej domeny, co zapobiega problemom z logowaniem. (Jeśli nie korzystasz z Hostingu Firebase, musisz skorzystać z innej opcji.)
Aby zaktualizować konfigurację Firebase, aby używać domeny niestandardowej jako domeny uwierzytelniania, wykonaj następujące czynności:
Skonfiguruj zestaw SDK Firebase JS, aby używał domeny niestandardowej jako domeny
authDomain
:const firebaseConfig = { apiKey: "<api-key>", authDomain: "<the-domain-that-serves-your-app>", databaseURL: "<database-url>", projectId: "<project-id>", appId: "<app-id>" };
Dodaj nową
authDomain
do listy autoryzowanych identyfikatorów URI przekierowań dostawcy OAuth. Sposób, w jaki to zrobisz, będzie zależał od dostawcy, ale ogólnie rzecz biorąc, możesz zapoznać się z sekcją „Zanim zaczniesz” u dowolnego dostawcy, aby uzyskać dokładne instrukcje (na przykład u dostawcy Facebooka ). Zaktualizowany identyfikator URI do autoryzacji wygląda następującohttps://<the-domain-that-serves-your-app>/__/auth/handler
— ważny jest końcowy/__/auth/handler
.Podobnie, jeśli korzystasz z dostawcy SAML, dodaj nową
authDomain
do adresu URL usługi SAML Assertion Consumer Service (ACS).
Opcja 2: Przełącz na funkcję SignInWithPopup()
Użyj funkcji signInWithPopup()
zamiast signInWithRedirect()
. Pozostała część kodu aplikacji pozostaje taka sama, ale obiekt UserCredential jest pobierany inaczej.
Modułowe API sieciowe
// Before
// ==============
signInWithRedirect(auth, new GoogleAuthProvider());
// After the page redirects back
const userCred = await getRedirectResult(auth);
// After
// ==============
const userCred = await signInWithPopup(auth, new GoogleAuthProvider());
Internetowy interfejs API z przestrzenią nazw
// Before
// ==============
firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
// After the page redirects back
var userCred = await firebase.auth().getRedirectResult();
// After
// ==============
var userCred = await firebase.auth().signInWithPopup(
new firebase.auth.GoogleAuthProvider());
```
Logowanie w wyskakujących okienkach nie zawsze jest idealne dla użytkowników — wyskakujące okienka są czasami blokowane przez urządzenie lub platformę, a przepływ informacji jest mniej płynny w przypadku użytkowników mobilnych. Jeśli używanie wyskakujących okienek stanowi problem w Twojej aplikacji, musisz skorzystać z jednej z pozostałych opcji.
Opcja 3: Wysyłaj żądania uwierzytelnienia proxy do firebaseapp.com
Przepływ signInWithRedirect
rozpoczyna się od przekierowania z domeny aplikacji do domeny określonej w parametrze authDomain
w konfiguracji Firebase („authDomain
hostuje kod pomocniczy logowania, który przekierowuje do dostawcy tożsamości, który, jeśli się powiedzie, przekierowuje z powrotem do domeny aplikacji.
Gdy przepływ uwierzytelniania powróci do domeny aplikacji, uzyskany zostanie dostęp do magazynu przeglądarki domeny pomocniczej logowania. Ta opcja i następna (do samodzielnego hostowania kodu) eliminują dostęp do pamięci między źródłami, który w przeciwnym razie byłby blokowany przez przeglądarki.
Skonfiguruj odwrotny serwer proxy na serwerze aplikacji, aby żądania GET/POST wysyłane do
https://<app domain>/__/auth/
były przekazywane dohttps://<project>.firebaseapp.com/__/auth/
. Upewnij się, że to przekazywanie jest przejrzyste dla przeglądarki; nie można tego zrobić za pomocą przekierowania 302.Jeśli używasz Nginx do obsługi domeny niestandardowej, konfiguracja odwrotnego proxy będzie wyglądać następująco:
# reverse proxy for signin-helpers for popup/redirect sign in. location /__/auth { proxy_pass https://<project>.firebaseapp.com; }
Wykonaj kroki opisane w Opcji 1 , aby zaktualizować autoryzowany
redirect_uri
, adres URL ACS iauthDomain
. Po ponownym wdrożeniu aplikacji dostęp do magazynu między źródłami nie powinien już mieć miejsca.
Opcja 4: samodzielnie hostuj kod pomocniczy do logowania w swojej domenie
Innym sposobem wyeliminowania dostępu do pamięci masowej z różnych źródeł jest samodzielne hostowanie kodu pomocniczego logowania Firebase. Jednak to podejście nie działa w przypadku logowania Apple ani protokołu SAML. Użyj tej opcji tylko wtedy, gdy konfiguracja odwrotnego proxy w opcji 3 jest niemożliwa.
Hostowanie kodu pomocniczego składa się z następujących kroków:
Pobierz pliki do hosta z lokalizacji
<project>.firebaseapp.com
, wykonując następujące polecenia:mkdir signin_helpers/ && cd signin_helpers wget https://<project>.firebaseapp.com/__/auth/handler wget https://<project>.firebaseapp.com/__/auth/handler.js wget https://<project>.firebaseapp.com/__/auth/experiments.js wget https://<project>.firebaseapp.com/__/auth/iframe wget https://<project>.firebaseapp.com/__/auth/iframe.js
Hostuj powyższe pliki w swojej domenie aplikacji. Upewnij się, że Twój serwer internetowy może odpowiedzieć na
https://<app domain>/__/auth/<filename>
.Oto przykładowa implementacja serwera , który pobiera i hostuje pliki. Zalecamy okresowe pobieranie i synchronizowanie plików, aby mieć pewność, że zostaną pobrane najnowsze poprawki błędów i funkcje.
Wykonaj kroki opisane w Opcji 1 , aby zaktualizować autoryzowane
redirect_uri
i swojąauthDomain
. Po ponownym wdrożeniu aplikacji dostęp do magazynu między źródłami nie powinien już mieć miejsca.
Opcja 5: Niezależna obsługa logowania dostawcy
Zestaw SDK uwierzytelniania Firebase udostępnia signInWithPopup()
signInWithRedirect()
jako wygodne metody umożliwiające zawinięcie skomplikowanej logiki i uniknięcie konieczności angażowania innego zestawu SDK. Możesz całkowicie uniknąć stosowania którejkolwiek z metod, niezależnie logując się do swojego dostawcy, a następnie używając signInWithCredential()
w celu wymiany poświadczeń dostawcy na poświadczenia uwierzytelniania Firebase. Możesz na przykład użyć pakietu SDK do logowania się za pomocą Google , przykładowego kodu , aby uzyskać dane uwierzytelniające konto Google, a następnie utworzyć nowe dane uwierzytelniające Google, uruchamiając następujący kod:
Modułowe API sieciowe
// `googleUser` from the onsuccess Google Sign In callback.
// googUser = gapi.auth2.getAuthInstance().currentUser.get();
const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
const result = await signInWithCredential(auth, credential);
Internetowy interfejs API z przestrzenią nazw
// `googleUser` from the onsuccess Google Sign In callback.
const credential = firebase.auth.GoogleAuthProvider.credential(
googleUser.getAuthResponse().id_token);
const result = await firebase.auth().signInWithCredential(credential);
Po wywołaniu metody signInWithCredential()
reszta aplikacji działa tak samo jak wcześniej.
Instrukcje dotyczące uzyskania certyfikatu Apple znajdują się tutaj .