使用上下文身份

許多人需要或希望使用多個身份在網路上進行互動。他們可能有用於工作和個人電子郵件的線上賬戶。他們可能會在訪問線上購物之前退出社交媒體賬戶,以確保購物網站上的任何跟蹤指令碼無法獲取其社交媒體活動。使用者通常會使用一個標準的私密瀏覽器視窗或兩個不同的瀏覽器來滿足這些需求。

為了滿足這一需求,Firefox 提供了一項名為“上下文身份”、“容器標籤頁”或“賬戶容器”的功能。此功能允許為使用者希望在其瀏覽器中使用的每個身份建立 cookie 容器(儲存)。標籤頁可以與其中一個身份相關聯,從而將 cookie 與瀏覽器中其他身份的 cookie 分開。其實際效果是,例如,使用者可以擁有一個個人身份和一個工作身份。然後,他們可以,例如,在一個標籤頁中使用個人身份登入他們的個人網頁郵件,在另一個標籤頁中使用工作身份登入他們的工作網頁郵件。

有關此功能的更多背景資訊,請參閱

用於處理上下文身份的 API

根據您的擴充套件的性質,您可能需要管理上下文身份、將您的擴充套件操作的物件與上下文身份相關聯,或兩者兼有。

管理上下文身份

要管理上下文身份,您需要使用 contextualIdentities API。此 API 允許您新增、查詢、更新和刪除上下文身份。當您建立上下文身份時,它會被賦予一個唯一的 cookieStoreId。您可以使用此 ID 來處理與上下文身份相關的實體。

使用 cookieStoreId

幾個擴充套件 API 在物件中包含 cookieStoreId,以允許擴充套件將這些物件與特定的上下文身份相關聯。

Permissions

要使用 contextualIdentities API,您必須在您的 manifest.json 檔案中包含“contextualIdentities” 許可權

如果 API 允許修改 cookie,您需要“cookies”許可權。例如,在 tabs.query 中使用 cookieStoreId 不需要“cookies”API,因為讀取屬性不會影響容器中的 cookie。但是,使用 tabs.create 需要該許可權,因為開啟的標籤頁可以讀取和修改容器中的 cookie。

示例詳解

示例擴充套件 contextual-identities 提供了一個帶有彈出視窗的工具欄按鈕,該彈出視窗列出了瀏覽器中的身份。對於每個身份,擴充套件都提供了使用其 cookie 容器建立標籤頁或移除其所有標籤頁的選項。

這是一個關於該擴充套件的簡短影片

manifest.json

manifest.json 檔案的一些主要功能是

  • 許可權請求

    json
      "permissions": [
          "contextualIdentities",
          "cookies"
      ],
    
  • 工具欄按鈕(browserAction)的規範,該按鈕提供對擴充套件功能的訪問

    json
      "browser_action": {
        "default_title": "Contextual Identities",
        "default_popup": "context.html",
        "default_icon": {
          "128": "identity.svg"
        }
    

context.html

工具欄按鈕上的彈出視窗提供了擴充套件的使用者介面。 context.html 實現此彈出視窗,但它只是一個外殼,context.js 指令碼將在此外殼中寫入上下文身份列表及其相關選項。

html
<body>
  <div class="panel">
    <div id="identity-list"></div>
  </div>
  <script src="context.js"></script>
</body>

context.js

該擴充套件的所有功能都透過 context.js 實現,每當工具欄彈出視窗顯示時都會呼叫它。

指令碼首先從 context.html 獲取 'identity-list' <div>。然後檢查上下文身份功能是否在瀏覽器中開啟。如果未開啟,則會將有關如何啟用該功能的資訊新增到彈出視窗中。

Firefox 安裝時上下文身份功能是關閉的。當安裝使用 contextualIdentities API 的擴充套件時,它會被開啟。但是,使用者也可以在首選項頁面(about:preferences)上透過一個選項將其關閉,因此需要進行檢查。

指令碼現在使用 contextualIdentities.query 來確定瀏覽器中是否定義了任何上下文身份。如果沒有,則會將一條訊息新增到彈出視窗中,指令碼將停止。

js
const div = document.getElementById("identity-list");
if (browser.contextualIdentities === undefined) {
  div.innerText =
    "browser.contextualIdentities not available. Check that the privacy.userContext.enabled pref is set to true, and reload the add-on.";
} else {
  browser.contextualIdentities.query({}).then((identities) => {
    if (!identities.length) {
      div.innerText = "No identities returned from the API.";
      return;
    }
    for (const identity of identities) {
      const row = document.createElement("div");
      const span = document.createElement("span");
      span.className = "identity";
      span.innerText = identity.name;
      span.style = `color: ${identity.color}`;
      console.log(identity);
      row.appendChild(span);
      createOptions(row, identity);
      div.appendChild(row);
    }
  });
}

如果存在上下文身份(Firefox 帶有四個預設身份),指令碼會迴圈遍歷每個身份,將其名稱(以其選定的顏色樣式顯示)新增到 <div> 元素中。然後 createOptions() 函式將“建立”或“關閉所有”的選項新增到 <div> 中,然後再將其新增到彈出視窗。

js
function createOptions(node, identity) {
  for (const option of ["Create", "Close All"]) {
    const a = document.createElement("a");
    a.href = "#";
    a.innerText = option;
    a.dataset.action = option.toLowerCase().replace(" ", "-");
    a.dataset.identity = identity.cookieStoreId;
    a.addEventListener("click", eventHandler);
    node.appendChild(a);
  }
}

指令碼現在等待使用者在彈出視窗中選擇一個選項。

如果使用者點選為某個身份建立標籤頁的選項,則會使用 tabs.create 透過傳遞該身份的 cookie 儲存 ID 來開啟一個標籤頁。

如果使用者選擇關閉該身份的所有標籤頁的選項,指令碼將執行一次 tabs.query 來獲取使用該身份的 cookie 儲存的所有標籤頁。然後指令碼將此標籤頁列表傳遞給 tabs.remove

js
function eventHandler(event) {
  if (event.target.dataset.action === "create") {
    browser.tabs.create({
      url: "about:blank",
      cookieStoreId: event.target.dataset.identity,
    });
  }

  if (event.target.dataset.action === "close-all") {
    browser.tabs
      .query({
        cookieStoreId: event.target.dataset.identity,
      })
      .then((tabs) => {
        browser.tabs.remove(tabs.map((i) => i.id));
      });
  }
  event.preventDefault();
}

瞭解更多

如果您想了解有關 contextualIdentities API 的更多資訊,請檢視