驗證狀態持續性

您可以指定使用 Firebase JS SDK 時,驗證狀態的保存方式。這包括指定登入使用者是否應無限期保留,直到使用者明確登出、關閉視窗或重新載入網頁時才清除。

對於網頁應用程式,預設行為是即使使用者關閉瀏覽器,仍會保留使用者的工作階段。這樣一來就很方便,因為使用者每次在同一部裝置上造訪網頁時,不必不斷登入。這可能會要求使用者重新輸入密碼、傳送簡訊驗證等,這可能會對使用者體驗造成許多阻礙。

不過,在某些情況下,這類行為可能不理想:

  • 含有機密資料的應用程式可能會在關閉視窗或分頁時清除狀態。這項功能非常重要,可避免使用者忘記登出。
  • 在多位使用者共用的裝置上使用的應用程式。常見的例子是圖書館電腦上執行的應用程式。
  • 共用裝置上的應用程式,可能會由多位使用者存取。開發人員無法得知應用程式的存取方式,因此可能會想讓使用者選擇是否要保留工作階段。您可以在登入時新增「記住我」選項,以便在下次登入時自動登入。
  • 在某些情況下,開發人員可能會選擇在使用者升級至非匿名帳戶 (聯合帳戶、密碼、電話號碼等) 前,不保留匿名使用者。
  • 開發人員可能會希望允許不同使用者在不同的分頁中登入應用程式。預設行為是針對同一個來源,在各分頁中保留狀態。

如上所述,在多種情況下,您可能需要覆寫預設的永久持久性。

支援的驗證狀態持續性類型

您可以根據應用程式或使用者需求,在指定的 Firebase Auth 例項中選擇其中一種 Auth 狀態持續性。

列舉 說明
firebase.auth.Auth.Persistence.LOCAL 'local' 表示即使瀏覽器視窗關閉或活動在 React Native 中遭到刪除,狀態仍會保留。您必須明確登出,才能清除該狀態。請注意,Firebase 驗證網頁工作階段是單一主機來源,且只會保留單一網域。
firebase.auth.Auth.Persistence.SESSION 'session' 表示狀態只會保留在目前的工作階段或分頁中,並在使用者驗證的分頁或視窗關閉時清除。僅適用於網頁應用程式。
firebase.auth.Auth.Persistence.NONE 'none' 表示狀態只會儲存在記憶體中,並會在視窗或活動重新整理時清除。

修改 Auth 狀態持續性

您可以呼叫 firebase.auth().setPersistence 方法,指定或修改現有的持久性類型:

Web

import { getAuth, setPersistence, signInWithEmailAndPassword, browserSessionPersistence } from "firebase/auth";

const auth = getAuth();
setPersistence(auth, browserSessionPersistence)
  .then(() => {
    // Existing and future Auth states are now persisted in the current
    // session only. Closing the window would clear any existing state even
    // if a user forgets to sign out.
    // ...
    // New sign-in will be persisted with session persistence.
    return signInWithEmailAndPassword(auth, email, password);
  })
  .catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
  });

Web

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
  .then(() => {
    // Existing and future Auth states are now persisted in the current
    // session only. Closing the window would clear any existing state even
    // if a user forgets to sign out.
    // ...
    // New sign-in will be persisted with session persistence.
    return firebase.auth().signInWithEmailAndPassword(email, password);
  })
  .catch((error) => {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
  });

這會針對目前儲存的 Auth 工作階段,變更指定 Auth 例項的持續性類型,並將這類持續性套用至日後的登入要求,包括使用重新導向要求登入。這會傳回承諾,當狀態從一種儲存空間複製到另一種儲存空間時,系統會解析承諾。在變更持久性後呼叫登入方法,會等待持久性變更完成,然後再將其套用至新的驗證狀態。

網路瀏覽器和 React Native 應用程式的預設值為 local (前提是瀏覽器支援此儲存機制,例如 啟用第三方 Cookie/資料),而 Node.js 後端應用程式則為 none

持久性行為簡介

判斷目前的持久性狀態時,系統會套用下列條件。

  • 一開始,SDK 會檢查是否有已驗證的使用者。除非呼叫 setPersistence,否則系統會在日後的登入嘗試中套用該使用者的目前持久化類型。因此,如果該使用者在先前網頁的 session 中保留狀態,且使用者造訪新頁面,則使用其他使用者再次登入時,該使用者的狀態也會透過 session 持續性功能儲存。
  • 如果沒有使用者登入且未指定持久性,系統會套用預設設定 (在瀏覽器應用程式中為 local)。
  • 如果沒有使用者登入,且已設定新類型的持久性,日後的登入嘗試都會使用該類型的持久性。
  • 如果使用者已登入,且持久化類型已修改,則該名已登入的使用者會將持久化變更為新類型。日後所有登入嘗試都會使用這個新的持久性。
  • 呼叫 signInWithRedirect 時,系統會保留目前的持久化類型,並在 OAuth 流程結束時套用至新登入的使用者,即使持久化類型為 none 也一樣。如果在該頁面上明確指定了持續性,系統會覆寫先前啟動重新導向流程的頁面中所保留的驗證狀態持續性。

    Web

    import { getAuth, setPersistence, signInWithRedirect, inMemoryPersistence, GoogleAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    setPersistence(auth, inMemoryPersistence)
      .then(() => {
        const provider = new GoogleAuthProvider();
        // In memory persistence will be applied to the signed in Google user
        // even though the persistence was set to 'none' and a page redirect
        // occurred.
        return signInWithRedirect(auth, provider);
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
      });

    Web

    firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE)
      .then(() => {
        var provider = new firebase.auth.GoogleAuthProvider();
        // In memory persistence will be applied to the signed in Google user
        // even though the persistence was set to 'none' and a page redirect
        // occurred.
        return firebase.auth().signInWithRedirect(provider);
      })
      .catch((error) => {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
      });

不同瀏覽器分頁的預期行為

在不同分頁中使用不同類型的持久性時,會發生下列預期行為。這項規定要求在任何時間點,都不得同時存在多種類型的已儲存狀態 (例如,在 sessionlocal 類型儲存空間中儲存的驗證狀態):

  • 使用者可以使用 sessionnone 持久性,在多個分頁中登入不同使用者。每個分頁都無法看到其他分頁的狀態。
  • 系統會偵測並在所有分頁上同步處理任何嘗試使用 local 持久性登入的情況。如果使用者先前曾在特定分頁中使用 sessionnone 持久性登入,系統會清除該狀態。
  • 如果使用者先前使用 local 持久性功能登入,並開啟多個分頁,然後切換至單一分頁中的 nonesession 持久性,系統會修改該分頁的狀態,並在 sessionnone 中保留使用者,在所有其他分頁中則將使用者登出。