使用上下文身份

许多人需要或希望使用多个身份与网络交互。他们可能拥有用于基于 Web 的工作和个人电子邮件的帐户。他们可能会在访问在线购物前退出社交媒体帐户,以确保购物网站上的任何跟踪脚本都无法获取他们的社交媒体活动。用户通常使用一个标准浏览器窗口和一个私有浏览器窗口或两个不同的浏览器来满足这些需求。

为了满足这一需求,Firefox 包含一项名为上下文身份、容器选项卡或帐户容器的功能。此功能允许为用户希望在浏览器中使用的每个身份创建一个 Cookie 容器(存储)。选项卡可以与其中一个身份相关联,使 Cookie 与浏览器中其他身份的 Cookie 相分离。实际上,这意味着用户可以使用一个个人身份和一个工作身份。例如,他们可以使用一个选项卡登录个人 Web 邮件,使用另一个选项卡登录工作 Web 邮件。

有关此功能的更多背景信息,请参阅

用于使用上下文身份的 API

根据扩展的性质,您可能希望管理上下文身份,将扩展操作的对象与上下文身份关联,或两者兼而有之。

管理上下文身份

要管理上下文身份,可以使用 contextualIdentities API。此 API 允许您添加、查询、更新和删除上下文身份。创建上下文身份时,会为其分配一个唯一的 cookieStoreId。您可以使用此 ID 操作与上下文身份相关的实体。

使用 cookieStoreId

几个扩展 API 在对象中包含 cookieStoreId,以使扩展能够将这些对象与特定的上下文身份关联。

权限

要使用 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>

js
let div = document.getElementById("identity-list");

然后,它会检查浏览器中是否启用了上下文身份功能。如果未启用,则会在弹出窗口中添加有关如何启用此功能的信息。

js
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 {

Firefox 在安装时会关闭上下文身份功能。安装使用 contextualIdentities API 的扩展时,此功能会打开。但是,用户可以通过首选项页面 (about:preferences) 上的选项关闭此功能,因此需要进行此检查。

脚本现在使用 contextualIdentities.query. 确定浏览器中是否定义了任何上下文身份。如果没有定义,则会在弹出窗口中添加一条消息,并且脚本会停止。

js
  browser.contextualIdentities.query({})
    .then((identities) => {
      if (!identities.length) {
        div.innerText = 'No identities returned from the API.';
        return;
      }

如果存在上下文身份(Firefox 带有四个默认身份),则脚本会循环遍历每个身份,将其名称(以其选择的颜色进行样式化)添加到 <div> 元素中。然后,createOptions() 函数会将 "创建" 或 "关闭所有" 选项添加到 <div> 中,然后再将其添加到弹出窗口中。

js
     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);
     }
  });
}

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);
  }
}

脚本现在会等待用户在弹出窗口中选择一个选项。

js
function eventHandler(event) {

如果用户单击为身份创建选项卡的选项,则会通过传递身份的 Cookie 存储库 ID 使用 tabs.create 打开一个选项卡。

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

如果用户选择关闭身份的所有选项卡的选项,则脚本会执行 tabs.query 以获取使用身份的 Cookie 存储库的所有选项卡。然后,脚本会将此选项卡列表传递给 tabs.remove

js
  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,请查看