在禁止第三方儲存空間存取的瀏覽器上使用 signInWithRedirect 的最佳做法

本文件將說明在瀏覽器上使用重新導向登入功能的最佳做法 並封鎖第三方 Cookie您必須採用本文列出的其中一個選項,signInWithRedirect() 才能在正式環境中透過任何瀏覽器正常運作。

總覽

為了讓 signInWithRedirect() 流程 Firebase Authentication JavaScript SDK 採用 可連結至應用程式 Firebase 託管網域的跨來源 iframe。 不過,如果是封鎖第三方功能的瀏覽器,就並不適用這項機制。 儲存空間存取權

由於要求使用者停用瀏覽器的儲存空間分區功能,這種情況很少見,因此建議您根據用途的特定用途,為應用程式套用下列其中一種設定選項。

  • 如果您是在 firebaseapp.com 的子網域使用 Firebase 託管應用程式代管應用程式,則不會受到這項問題影響,因此無須採取任何行動。
  • 如果您是透過自訂網域或 web.app 的子網域透過 Firebase 託管應用程式,請使用 選項 1
  • 如果您透過 Firebase 以外的服務託管應用程式,請使用 選項 2選項 3選項 4、 或選項 5

方法 1:更新 Firebase 設定,將自訂網域設為authDomain

如果您使用自訂網域透過 Firebase 託管來託管應用程式,可以 請設定 Firebase SDK,將自訂網域做為 authDomain。這個 可確保應用程式和驗證 iframe 使用相同的網域, 登入問題。(如果您沒有使用 Firebase 託管,就必須使用 不同的選項)。確認你在同一個網域中設定自訂網域 。

如要更新 Firebase 設定,將自訂網域做為驗證網域,請按照下列步驟操作: 包括:

  1. 將 Firebase JS SDK 設為將自訂網域做為 authDomain

    const firebaseConfig = {
      apiKey: "<api-key>",
      authDomain: "<the-domain-that-serves-your-app>",
      databaseURL: "<database-url>",
      projectId: "<project-id>",
      appId: "<app-id>"
    };
    
,瞭解如何調查及移除這項存取權。
  1. 將新的 authDomain 新增至 OAuth 供應商的授權清單 重新導向 URI執行方法取決於各供應商,但一般而言皆是如此 請按照「事前準備」部分 指示 (例如 Facebook 供應商)。更新後的 URI 授權看起來 https://<the-domain-that-serves-your-app>/__/auth/handler - 結尾 /__/auth/handler很重要。

    同樣地,如果您使用的是 SAML 提供者,請將新的 authDomain 新增至 SAML 宣告客戶服務 (ACS) 網址。

  2. 確認continue_uri已列入授權網域清單。

  3. 如有需要,請透過 Firebase 託管重新部署 /__/firebase/init.json 託管的最新 Firebase 設定檔。

方法 2:切換至 signInWithPopup()

signInWithPopup() 取代 signInWithRedirect()。 應用程式的其他程式碼則維持不變,但 UserCredential 物件 個別擷取。

Web

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

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

Web

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

彈出式視窗登入有時不見得適合使用者, 裝置和平台,行動裝置使用者的流程較不順暢。如果使用 彈出式視窗的應用程式有問題,您需要遵循 只要設定成「自動重新啟動」 和「在主機維護期間」選項即可

方法 3:透過 Proxy 將驗證要求傳送至 firebaseapp.com

signInWithRedirect 流程一開始會從您的應用程式網域重新導向至 Firebase 設定 authDomain 參數中指定的網域 (預設為「.firebaseapp.com」)。authDomain 會代管登入小幫手 重新導向至「身分提供程式」的程式碼,成功之後,會重新導向回 並上傳至應用程式網域

驗證流程返回您的應用程式網域時, 登入輔助網域這個選項和 (用來自行代管程式碼) 會消除跨來源儲存空間存取權,否則會遭到瀏覽器封鎖。

  1. 在應用程式伺服器上設定反向 Proxy,以便將 GET/POST 要求傳送至 系統已將 https://<app domain>/__/auth/ 轉寄到 https://<project>.firebaseapp.com/__/auth/。 確保瀏覽器公開透明。但無法透過 302 重新導向進行

    如果您使用 nginx 提供自訂網域,反向 Proxy 設定會如下所示:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. 請按照 選項 1 更新授權的 redirect_uri、ACS 網址和您的 authDomain。重新部署之後 時,應不會再有跨來源儲存空間存取權。

方法 4:自行託管網域中的登入輔助程式碼

取消跨來源儲存空間存取權的另一個方法是自行託管 Firebase 登入輔助程式碼。不過,這種方法不適用於 Apple 登入或 SAML 登入。只有在以下時間點採用反向 Proxy 的情況下,才能使用這個選項 選項 3 不適用

代管輔助程式碼的步驟如下:

  1. 下載以下 <project>.firebaseapp.com 位置要代管的檔案: 執行下列指令:

    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
    wget https://<project>.firebaseapp.com/__/firebase/init.json
    
  2. 請在您的應用程式網域下代管上述檔案。確認網路伺服器 可以回應https://<app domain>/__/auth/<filename>https://<app domain>/__/firebase/init.json

    以下是下載及代管檔案的伺服器實作範例。 建議您定期下載並同步處理檔案,確保獲得最新的錯誤修正及功能。

  3. 請按照 選項 1 更新已授權的 redirect_uri 和您的 authDomain。重新部署之後 時,應不會再有跨來源儲存空間存取權。

選項 5:獨立處理供應商登入作業

Firebase Authentication SDK 提供 signInWithPopup()signInWithRedirect(),目前擔任 方便包裝複雜邏輯並避免 其他 SDK。您可以避免單獨使用上述任一方法, 連結供應商, signInWithCredential() 到 也就是將供應商的憑證交換為 Firebase 驗證憑證。 舉例來說,您可以使用 Google Sign In SDK 程式碼範例 取得 Google 帳戶憑證,然後將新的 Google 憑證執行個體化 請執行下列程式碼:

Web

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

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

呼叫 signInWithCredential() 後,應用程式的其餘部分就會運作 做法和之前一樣

取得 Apple 憑證的操作說明如下 請按這裡