Najlepsze praktyki dotyczące używania signInWithRedirect w przeglądarkach, które blokują dostęp do magazynu innych firm

W tym dokumencie opisano najlepsze praktyki dotyczące korzystania z logowania przez przekierowanie w przeglądarkach, które blokują pliki cookie innych firm. Aby funkcja signInWithRedirect() działała zgodnie z przeznaczeniem w środowiskach produkcyjnych we wszystkich przeglądarkach, należy postępować zgodnie z jedną z wymienionych tutaj opcji.

Przegląd

Aby proces signInWithRedirect() przebiegał bezproblemowo dla Ciebie i Twoich użytkowników, pakiet SDK JavaScript do uwierzytelniania Firebase używa ramki iframe z różnych źródeł, która łączy się z domeną Hostingu Firebase Twojej aplikacji. Jednak ten mechanizm nie działa z przeglądarkami, które blokują dostęp do pamięci masowej innych firm.

Ponieważ proszenie użytkowników o wyłączenie funkcji partycjonowania pamięci masowej w przeglądarce rzadko wchodzi w grę, zamiast tego należy zastosować w aplikacji jedną z poniższych opcji konfiguracji, w zależności od specyfiki przypadku użycia.

  • Jeśli hostujesz swoją aplikację za pomocą Hostingu Firebase w subdomenie firebaseapp.com , ten problem Cię nie dotyczy i nie musisz nic robić.
  • Jeśli hostujesz swoją aplikację za pomocą Hostingu Firebase w domenie niestandardowej lub subdomenie web.app , użyj Opcji 1 .
  • Jeśli hostujesz swoją 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ła domeny niestandardowej jako domeny authDomain

Jeśli hostujesz swoją aplikację za pomocą Hostingu Firebase przy użyciu domeny niestandardowej, możesz skonfigurować pakiet Firebase SDK tak, aby używał domeny niestandardowej jako authDomain . Dzięki temu aplikacja i element iframe uwierzytelniania korzystają z tej samej domeny, co zapobiega problemom z logowaniem. (Jeśli nie korzystasz z Hostingu Firebase, musisz użyć innej opcji).

Aby zaktualizować konfigurację Firebase, aby używała domeny niestandardowej jako domeny uwierzytelniania, wykonaj następujące czynności:

  1. Skonfiguruj Firebase JS SDK, aby używał domeny niestandardowej jako authDomain :

    const firebaseConfig = {
      apiKey: "<api-key>",
      authDomain: "<the-domain-that-serves-your-app>",
      databaseURL: "<database-url>",
      projectId: "<project-id>",
      appId: "<app-id>"
    };
    
  2. Dodaj nową authDomain do listy autoryzowanych identyfikatorów URI przekierowania dostawcy OAuth. Sposób, w jaki to zrobisz, zależy od dostawcy, ale generalnie możesz postępować zgodnie z sekcją „Zanim zaczniesz” u dowolnego dostawcy, aby uzyskać dokładne instrukcje (na przykład dostawca Facebooka ). Zaktualizowany identyfikator URI do autoryzacji wygląda tak https://<the-domain-that-serves-your-app>/__/auth/handler — końcowy /__/auth/handler jest ważny.

    Podobnie, jeśli używasz dostawcy SAML, dodaj nową authDomain do adresu URL SAML Assertion Consumer Service (ACS).

Opcja 2: przełącz się na signInWithPopup()

Użyj signInWithPopup() zamiast signInWithRedirect() . Pozostała część kodu aplikacji pozostaje taka sama, ale obiekt UserCredential jest pobierany w inny sposób.

Web version 9

  // Before
  // ==============
  signInWithRedirect(auth, new GoogleAuthProvider());
  // After the page redirects back
  const userCred = await getRedirectResult(auth);

  // After
  // ==============
  const userCred = await signInWithPopup(auth, new GoogleAuthProvider());

Web version 8

  // 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 jest mniej płynny dla użytkowników mobilnych. Jeśli korzystanie z wyskakujących okienek stanowi problem dla 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 Twojej aplikacji do domeny określonej w parametrze authDomain w konfiguracji Firebase („ .firebaseapp.com” authDomain ).

Gdy przepływ uwierzytelniania powraca do domeny aplikacji, uzyskuje się dostęp do magazynu przeglądarki domeny pomocnika logowania. Ta opcja i następna (do samodzielnego hostowania kodu) eliminuje dostęp do pamięci między źródłami, który w przeciwnym razie jest blokowany przez przeglądarki.

  1. Skonfiguruj zwrotny serwer proxy na serwerze aplikacji, aby żądania GET/POST do https://<app domain>/__/auth/ były przekazywane do https://<project>.firebaseapp.com/__/auth/ . Upewnij się, że to przekazywanie jest przezroczyste 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ć tak:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. Wykonaj czynności opisane w Opcji 1 , aby zaktualizować autoryzowane redirect_uri , ACS URL i swoją authDomain . Po ponownym wdrożeniu aplikacji dostęp do pamięci między źródłami nie powinien już mieć miejsca.

Opcja 4: samodzielnie hostuj kod pomocniczy logowania w swojej domenie

Innym sposobem na wyeliminowanie 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 serwera proxy w opcji 3 jest niewykonalna.

Hosting kodu pomocniczego składa się z następujących kroków:

  1. Pobierz pliki do hostowania 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
    
  2. Hostuj powyższe pliki w swojej domenie aplikacji. Upewnij się, że serwer WWW może odpowiedzieć na https://<app domain>/__/auth/<filename> .

    Oto przykładowa implementacja serwera , która pobiera i przechowuje pliki. Zalecamy okresowe pobieranie i synchronizowanie plików, aby zapewnić pobieranie najnowszych poprawek błędów i funkcji.

  3. Wykonaj czynności opisane w opcji 1 , aby zaktualizować autoryzowane redirect_uri i swoją authDomain . Po ponownym wdrożeniu aplikacji dostęp do pamięci między źródłami nie powinien już mieć miejsca.

Opcja 5: niezależnie obsługuj logowanie dostawcy

Zestaw SDK uwierzytelniania Firebase zapewnia signInWithPopup() i signInWithRedirect() jako wygodne metody owijania skomplikowanej logiki i unikania konieczności angażowania innego zestawu SDK. Możesz całkowicie uniknąć korzystania z obu metod, niezależnie logując się do swojego dostawcy, a następnie używając signInWithCredential() do wymiany poświadczeń dostawcy na poświadczenia uwierzytelniania Firebase. Możesz na przykład użyć przykładowego kodu Google Sign In SDK , aby uzyskać dane logowania do konta Google, a następnie utworzyć instancję nowych danych logowania Google, uruchamiając następujący kod:

Web version 9

  // `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);

Web version 8

  // `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 uzyskiwania poświadczeń Apple znajdują się tutaj .