MSAL.js 中的快取

當 MSAL 取得一個代幣時,會將其快取以供未來使用。 MSAL 會幫你管理代幣壽命和刷新。 acquireTokenSilent() API 會從快取中擷取指定帳戶的存取權杖,並在需要時重新整理這些權杖。

快取存放區

你可以透過用來實例化 MSAL 的設定物件來設定快取儲存位置:

import { PublicClientApplication, BrowserCacheLocation } from "@azure/msal-browser";

const pca = new PublicClientApplication({
    auth: {
        clientId: "Enter_the_Application_Id_Here", // e.g. "00001111-aaaa-2222-bbbb-3333cccc4444" (guid)
        authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here", // e.g. "common" or your tenantId (guid),
        redirectUri: "/"
    },
    cache: {
       cacheLocation: BrowserCacheLocation.SessionStorage // "sessionStorage"
    }
});

預設情況下,MSAL 會將從 IdP 取得的各種認證產物儲存在瀏覽器儲存中,使用所有現代瀏覽器支援的 Web Storage API 。 因此,MSAL 提供兩種持久儲存方法: sessionStorage (預設)與 localStorage。 此外,MSAL 提供 memoryStorage 選項,可讓你選擇不將快取儲存在瀏覽器儲存體中。

快取位置 已清除 視窗/分頁間共享 支援重定向流
sessionStorage 視窗/分頁關閉 No Yes
localStorage 瀏覽器關閉(除非使用者選擇「保持我登入」) Yes Yes
memoryStorage 頁面刷新/導覽 No No

Note

雖然驗證狀態可能因視窗/分頁關閉或頁面刷新/導航而在會話和記憶體儲存中遺失,但只要會話 cookie 未過期,使用者仍與 IdP 保持活躍會話,且可能能在不需提示的情況下重新認證。

選擇不同儲存地點,反映出在更佳使用者體驗與提升安全性之間的權衡。 如上表所示,本地儲存能帶來最佳的使用者體驗,而記憶體儲存則提供最佳安全性,因為瀏覽器儲存中不會儲存敏感資訊。 詳情請參閱下方 關於安全性快取文物 的章節。

LocalStorage 備註

從 v4 開始,如果您使用 localStorage 快取位置,驗證成品會經過加密,除非使用者在登入時選擇「讓我保持登入狀態」。 所使用的加密演算法為 AES-GCM ,利用 HKDF 來推導金鑰。 基礎金鑰儲存在一個名為 msal.cache.encryption的會話 Cookie 中。

當瀏覽器實例(非 Tab)關閉時,這個 Cookie 會自動移除,導致會話結束後無法解密任何認證痕跡。 這些過期的驗證產出會在下次 MSAL 初始化時移除,使用者可能需要重新驗證。 該 localStorage 位置仍可為所有使用者提供跨分頁的快取持續性,但只有選取「讓我保持登入狀態」(KMSI)的使用者,才能在瀏覽器工作階段之間持續保留快取。

Important

此加密的目的是降低認證偽物的持久性, 而非 提供額外安全性。 如果惡意行為者取得瀏覽器儲存空間的存取權,他們也能取得金鑰,或能代表你請求憑證,完全不需要快取。 確保你的應用程式不會受到 XSS 攻擊是你的責任。 詳情請參見 安全 部分。

Note

在 MSAL.js v4 中,暫存驗證產物的 Cookie 儲存功能已被棄用。 此部分保留給仍在使用 MSAL.js v3 或更早版本的應用程式。

MSAL 瀏覽器可設定使用 Cookie 來儲存臨時驗證產物。 此選項可讓您支援某些可能會在重新導向式登入流程期間清除本機儲存空間或工作階段儲存空間的瀏覽器(例如 Internet Explorer,以及私密瀏覽模式下的 Firefox)。 請注意,選擇此選項時,標記本身仍會儲存在瀏覽器或記憶體中。 詳情請參閱 配置

安全性

我們認為會話/本地儲存是安全的,只要你的應用程式沒有跨站腳本(XSS)及相關漏洞。 請參閱 OWASP XSS 防範速查表 ,以確保您的申請能防範 XSS。 如果你仍然擔心,我們建議改用這個 memoryStorage 選項。

快取的產物

為了在維持良好使用者體驗的同時,方便高效取得令牌,MSAL 會快取由 API 呼叫產生的各種產物。 以下為 MSAL 快取中各實體的摘要:

  • 持久性成品(在要求完成後仍會持續存在——另請參閱:權杖存留時間
    • 存取憑證
    • ID 標記
    • 刷新代幣
    • accounts
  • 暫時性產物(僅限於請求生命週期)
    • 請求元資料(例如 state、nonce、authority)
    • 錯誤
    • 互動狀態
  • 遙測
    • 先前未果的請求
    • 效能數據

Note

暫時快取項目一律儲存於工作階段儲存空間或記憶體中。 如果沒有會話儲存空間,MSAL 會退回到記憶體儲存。

Note

授權碼僅存於記憶體中,兌換代幣後會被丟棄。

temporaryCacheLocation 覆寫

Note

temporaryCacheLocation 設定選項在 MSAL.js v4 中已被棄用。 此部分保留給仍在使用 MSAL.js v3 或更早版本的應用程式。

Warning

覆寫 temporaryCacheLocation 時應謹慎操作,尤其是在選擇 localStorage 時。 不支援在多個分頁或視窗互動,可能會意外收到 interaction_in_progress 錯誤。 這是逃生出口,並非完全支援的功能。

當使用者在成功認證後被導向到新視窗或分頁的情況下,使用預設設定的 MSAL.js 時,帶有 PKCE 流程的 OAuth 2.0 授權碼會被中斷。 此時,儲存驗證狀態(程式碼驗證器與挑戰)的原始視窗或分頁將遺失,認證流程也會失敗。

為了處理這種情況,你可以透過覆寫 temporaryCacheLocation 設定屬性,將 MSAL 設定為使用 localStorage 作為快取位置。 這可讓程式碼驗證器和驗證挑戰儲存在瀏覽器的 localStorage 中,且可在多個頁籤和視窗之間持續保留。

MSAL.js 升級與回滾期間的快取持久性

有時 MSAL.js 需要修改快取產物的形狀,以支援新需求、新功能或錯誤修正。 這些變更通常以向下相容的方式進行,以確保當應用程式升級到新版本或回滾到舊版本時,使用者瀏覽器中的快取仍能被使用。 不過這並非總是可行,你可能會遇到多個快取副本同時存在的情況,一個是目前 MSAL.js 版本使用的,另一個是升級前版本寫入的。 這樣做是為了讓應用程式在需要時能優雅地回滾。 在絕大多數升級中,MSAL.js 會將現有快取遷移到新格式,以實現無縫升級體驗。 在極少數情況下,例如從 v3 升級到 v4,可能因安全或隱私需求而無法實現,這通常會導致版本大幅提升。

當對快取進行重大變更時,依預設會保留舊的快取 5 天,以便在需要時進行回滾。 舊快取的保留時間可使用在 PublicClientApplication 上的 cacheRetentionDays 快取設定來設定。 如果快取在這段時間內沒有被積極使用,下次初始化時 MSAL.js 快取就會被清除。 此外,如果你預期不需要回復舊版,也可以將此值設為 0,表示每次升級至新版 MSAL.js 時,都應一律立即移除舊快取。 反之,如果你的升級推出窗口較長,也可以選擇將此值設定為較長的數值。

Note

存取權杖和刷新權杖一旦過期就會被移除,即使 cacheRetentionDays 設定時間還沒達到。 若瀏覽器儲存量達到其儲存配額,有效的存取權杖也可能隨時被移除。 當儲存配額達到時,存取權杖會依先入先出原則移除,先從前一版本 MSAL.js 所寫的條目開始,然後依序移除由目前版本的 MSAL.js所寫的條目。

const config = {
    auth: {
        clientId: "<your-client-id>"
    },
    cache: {
        cacheLocation: "localStorage",
        cacheRetentionDays: 0 // Set this to the number of days you want old cache to be preserved in the event a rollback is needed (Default 5 days)
    }
}

const pca = new PublicClientApplication(config);
await pca.initialize();

備註

  • 我們不建議應用程式的業務邏輯依賴於直接使用快取中的實體。 相反地,當你需要取得代幣或取回帳號時,請使用適當的 MSAL API。
  • 用於加密擁有證明(PoP)令牌的金鑰,是透過 IndexedDB API 與記憶體儲存的組合來儲存的。 欲了解更多資訊,請參閱 存取權證證明(access-token-proof-of-possession)條目。

詳細資訊