权限

与强大功能的权限交互

W3C 工作草案

更多关于此文档的细节
此版本:
https://www.w3.org/TR/2024/WD-permissions-20241220/
最新发布版本:
https://www.w3.org/TR/permissions/
最新编辑草案:
https://w3c.github.io/permissions/
历史:
https://www.w3.org/standards/history/permissions/
提交历史
编辑:
Marcos Cáceres (苹果公司)
Mike Taylor (谷歌公司)
前编辑:
Mounir Lamouri (谷歌公司)
Jeffrey Yasskin (谷歌公司)
反馈:
GitHub w3c/permissions (拉取请求新问题开放问题)
浏览器支持:
Chrome logo43
Edge logo79
Firefox logo46
Safari logo16.0
桌面版
Android Chrome 图标131
Android Firefox 图标132
Android UC 图标15.5
iOS Safari 图标16.0
三星互联网图标4
移动设备
更多信息

摘要

本规范定义了其他规范可以用来与浏览器权限交互的通用基础设施。这些权限代表用户对平台“强大功能”访问的允许或拒绝选择。对于开发人员来说,本规范标准化了一个API,用于查询强大功能的权限状态,并在使用强大功能的权限状态发生变化时接收通知。

本文档的状态

本节描述了本文档在发布时的状态。当前W3C出版物列表及本技术报告的最新修订版本可在W3C技术报告索引中找到,网址为:https://www.w3.org/TR/。

本文档正在开发中。

本文档由 Web 应用程序安全工作组 作为工作草案发布, 采用推荐标准流程

作为工作草案发布并不意味着W3C及其成员的认可。

本文档是草稿,可能随时被更新、替换或废弃。引用本文档时只能作为工作进展的参考。

本文档由一个在 W3C 专利政策下运作的团体制定。 W3C 维护一个 与该团体交付成果相关的任何专利披露的公开列表; 该页面还包含披露专利的说明。任何实际知晓某项专利,并认为该专利包含 必要权利要求的个人, 必须根据 W3C 专利政策第 6 节披露该信息。

本文档受 2023年11月3日 W3C 流程文档的约束。

1. 介绍

本节为非规范性内容。

规范可以定义被明确标识为强大功能的特性。这些特性之所以被称为“强大”,是因为它们可能对隐私、安全性和性能产生重大影响。因此,用户依赖用户代理来拒绝网站使用这些特性,直到用户明确授予权限,并且通常仅限于授予一段有限的时间。允许网站使用强大功能的明确权限通常通过浏览器UI来授予和控制,如下图所示。

左侧是通知提示的模型,带有允许和不允许按钮,内容显示'网站example.com希望向您发送通知'。右侧是靠近URL栏的提示,要求授予网站对相机和麦克风的访问权限。
1 可能的权限提示类型示意图

从这个意义上说,权限表示用户对某些类型功能,尤其是“强大功能”的当前同意状态。最终,用户保留这些权限的控制权,并有能力通过用户偏好手动授予或拒绝权限。此外,用户代理帮助用户管理权限,例如,隐藏和自动拒绝某些可能造成麻烦的权限提示,并在用户长时间未访问某个网站时自动使已授予的权限过期。

一个设置页面的模型,允许用户为位置、相机、麦克风、运动传感器和通知权限设置或重置默认设置。
2 可能的站点特定权限控制UI示意图

2. 使用示例

本节为非规范性内容。

本示例使用权限API决定是否通过地理位置API显示本地新闻,或提供一个按钮以添加该功能。

示例 1:使用.state属性
const { state } = await navigator.permissions.query({
  name: "geolocation"
});
switch (state) {
  case "granted":
    showLocalNewsWithGeolocation();
    break;
  case "prompt":
    showButtonToEnableLocalNews();
    break;
  case "denied":
    showNationalNews();
    break;
}

本示例同时检查"geolocation""notifications" 强大功能的状态:

示例 2:检查多个权限的状态
const queryPromises = ["geolocation", "notifications"].map(
  name => navigator.permissions.query({ name })
);
for await (const status of queryPromises) {
  console.log(`${status.name}: ${status.state}`);
}

本示例正在检查可用摄像头的权限状态。

示例 3:检查多个摄像头的权限状态
const devices = await navigator.mediaDevices.enumerateDevices();

// filter on video inputs, and map to query object
const queries = devices
  .filter(({ kind }) => kind === "videoinput")
  .map(({ deviceId }) => ({ name: "camera", deviceId }));

const promises = queries.map((queryObj) =>
  navigator.permissions.query(queryObj)
);

try {
  const results = await Promise.all(promises);
  // log the state of each camera
  results.forEach(({ state }, i) => console.log("Camera", i, state));
} catch (error) {
  console.error(error);
}

3. 模型

本节为权限在Web平台上使用强大功能指定了一个模型。

3.1 权限

权限表示用户允许Web应用程序使用强大功能的决策。该决策以权限状态表示。

明确权限指用户授予Web应用程序使用强大功能的能力。

注意:限制和可扩展性

从概念上讲,强大功能的权限可以处于以下状态之一:

"拒绝"
用户或代表用户的用户代理已拒绝访问此强大功能。调用者将无法使用该功能。
"授予"
用户或代表用户的用户代理已授予明确许可来使用强大功能。调用者将能够使用该功能,可能无需用户代理询问用户许可。
"提示"
用户尚未授予使用该功能的明确许可(即,与“拒绝”相同)。这也意味着,如果调用者尝试使用该功能,用户代理要么会提示用户授予权限,要么对该功能的访问将被“拒绝”

为了获取用户意图的新信息,用户代理可以收集并解释用户意图的信息。这些信息可以来自用户的明确操作、相关用户和其他用户的汇总行为,或本文档未预见的隐式信号

注意: 什么构成隐式信号?

每个权限都有一个生命周期, 指的是特定权限在恢复到其默认状态之前保持“授予”状态的持续时间。一个生命周期 可能持续到特定的领域 (Realm) 被销毁,直到特定的 顶级浏览上下文被销毁,一段特定的时间,或者是无限的。 当用户通过权限用户界面或用户代理定义的策略授予使用某个功能明确许可时,生命周期由最终用户和用户代理协商确定。

每个权限都有一个默认状态(通常是"提示"),这是指用户尚未授予明确权限使用该功能或由于其生命周期到期而被重置时的状态。

3.2 权限存储

用户代理维护一个单一的权限存储,它是一个权限存储条目列表。每个由其描述符表示的特定条目在此列表中最多只能出现一次。

当相应权限生命周期已过期时,用户代理可以权限存储中移除条目

一个权限存储条目是一个由PermissionDescriptor 描述符权限键 状态 状态组成的元组

给定一个PermissionDescriptor 描述符和一个权限键 ,要获取权限存储条目

  1. 如果用户代理的权限存储包含一个条目,其描述符描述符,并且其在给定描述符的情况下等于,则返回该条目。
  2. 返回 null。

给定一个PermissionDescriptor 描述符、一个权限键 和一个状态 状态,要设置权限存储条目,请执行以下步骤:

  1. newEntry 为一个新的权限存储条目,其描述符描述符,其, 其状态状态
  2. 如果用户代理的权限存储包含一个条目,其描述符描述符,并且其在给定描述符的情况下等于,则替换该条目为newEntry并中止这些步骤。
  3. newEntry附加到用户代理的权限存储

给定一个PermissionDescriptor 描述符和一个权限键 ,要移除权限存储条目,请执行以下步骤:

  1. 从用户代理的权限存储移除描述符描述符,并且其在给定描述符的情况下等于条目

权限键的类型由功能的权限键类型定义。

注意

要确定权限键key1是否与权限键key2 相等,在给定PermissionDescriptor 描述符的情况下,请执行以下步骤:

  1. 如果key1不是描述符权限键类型,或者key2不是描述符权限键类型,则返回false。
  2. 返回为由描述符name命名的功能运行权限键比较算法的结果,传递key1key2

3.3 强大功能

强大功能是指用户在使用前需要给予明确许可的 Web 平台功能(通常是 API)。 除少数显著例外(例如,通知 API 标准),大多数强大功能也是策略控制的功能。对于同时也是策略控制的功能的强大功能,[权限策略] 控制文档是否允许使用给定的功能。 也就是说,只有当文档通过相应的策略控制的功能获得了权限委派时,强大功能才能向用户请求明确许可(参见下面的示例)。 后续对该功能的访问取决于用户是否已“授予”权限,或者满足某些等同于权限授予的标准。

强大功能由其名称标识,该名称是一个字符串字面量(例如,“geolocation”)。

用户代理通过环境设置对象跟踪用户拥有使用哪些强大功能权限

3.3.1 方面

每个强大功能可以定义零个或多个额外的方面。方面定义为 WebIDL 字典,它继承PermissionDescriptor 并用作 WebIDL 接口的权限描述符类型

3.4 权限任务来源

权限任务源是一个任务源,用于在本规范中执行与权限相关的任务

4. 指定强大功能

当符合规范指定强大功能时,它:

  1. 必须强大功能提供一个名称,其形式为ASCII 小写字符串。
  2. 可以定义一个权限描述符类型,该类型继承自PermissionDescriptor
  3. 可以定义零个或多个方面
  4. 可以在默认值不适用于特定强大功能的情况下,覆盖以下算法和类型。
  5. 必须权限注册表中注册强大功能

权限注册表中注册新指定的强大功能,为该工作组提供了反馈机会,并检查与本规范的集成是否有效。

权限描述符类型

PermissionDescriptor或其子类型。如果未指定,默认值为PermissionDescriptor

该功能可以定义描述符实例的部分顺序。如果descriptorA强于descriptorB,则如果descriptorA权限状态为"granted",则descriptorB权限状态也必须为"granted",如果descriptorB权限状态为"denied",则descriptorA权限状态也必须为"denied"。

权限状态约束
限制用户代理可以作为描述符的权限状态返回的值。默认情况下,除了用户意图之外没有其他约束。
额外权限数据类型

某些强大功能比仅仅提供一个PermissionState关联了更多信息。这些功能中的每一个都定义了一个额外权限数据类型

注意

例如,getUserMedia() 需要确定用户已授予访问权限的哪些摄像头。

如果 DOMString name 命名了这些功能之一,那么 name额外权限数据(对于一个可选的环境设置对象 settings)是以下算法的结果:

  1. 如果未传递 settings,则将其设置为当前设置对象
  2. 如果先前曾使用相同的 namesettings 调用此算法并返回了 previousResult,并且自该调用以来用户代理未收到关于用户意图的新信息,则返回 previousResult
  3. 返回与用户代理对用户意图的印象相匹配的 name额外权限数据类型的实例,同时考虑 name 的任何额外权限数据约束

如果指定,则该额外权限数据算法可用于此功能。

可选的额外权限数据约束
限制用户代理可以作为额外权限数据返回的强大功能的值。默认情况下,除了用户意图之外没有其他约束。
权限结果类型
PermissionStatus或其子类型。如果未指定,默认值为PermissionStatus
权限查询算法

接收一个权限描述符类型实例和一个新的或现有的权限结果类型实例,并更新权限结果类型实例的查询结果。由Permissionsquery(permissionDesc)方法和PermissionStatus更新步骤使用。如果未指定,默认使用默认权限查询算法

默认权限查询算法,给定一个PermissionDescriptorpermissionDesc和一个PermissionStatusstatus,运行以下步骤:

  1. 设置statusstatepermissionDesc权限状态
权限键类型

该功能使用的权限密钥的类型。默认为源 (origin)。指定自定义权限密钥类型的功能必须同时指定一个权限密钥生成算法

权限键生成算法

接受一个环境设置对象,并返回一个新的权限密钥。如果未指定,则默认为默认权限密钥生成算法。 指定自定义权限密钥生成算法的功能必须同时指定一个权限密钥比较算法

默认权限密钥生成算法,给定一个环境设置对象 settings,运行以下步骤:

  1. 返回 settings顶级源
注意:权限委托
权限键比较算法

接受两个权限密钥并返回一个布尔值,该布尔值显示两个密钥是否相等。如果未指定,则默认为默认权限密钥比较算法

默认权限密钥比较算法,给定权限密钥 key1key2,运行以下步骤:

  1. 如果 key1key2 同源,则返回 true。
权限撤销算法

不接收任何参数。更新实现中的其他部分,使其与权限状态额外权限数据的变化保持同步。

如果未指定,默认运行响应用户撤销权限

权限生命周期

定义一个或多个强大功能的规范应该建议最适合特定功能的权限生命周期。 以下提供了一些确定权限生命周期的指南,重点是用户隐私。如果未指定生命周期,则由用户代理提供。

当来源的权限生命周期到期时:

  1. 将权限设置回其默认的权限状态(例如,通过将其设置回“提示”)。
  2. 对于与源关联的每个浏览上下文(如果有),在权限任务源上使用浏览上下文全局对象排队一个全局任务,以运行权限撤销算法
注意:确定权限生命周期
默认权限状态

一个PermissionState值,用作权限默认状态,适用于强大功能

如果未指定,权限默认状态为 "提示"。

一个默认强大功能是一个强大功能,其所有类型和算法都使用默认值。

5. 与权限交互的算法

5.1 读取当前权限状态

获取当前权限状态,给定一个名称 name 和一个可选的环境设置对象 settings,请运行以下步骤。此算法返回一个 PermissionState 枚举值。

  1. descriptor 成为一个新创建的PermissionDescriptor,其 name 被初始化为 name
  2. 返回 descriptor权限状态,并带有settings

一个 描述符权限状态,给定一个可选的环境设置对象 settings,是以下算法的结果。 它返回一个 PermissionState 枚举值:

  1. 如果未传递 settings,则将其设置为当前设置对象
  2. 如果 settings 是一个非安全上下文,则返回“denied”。
  3. feature描述符name
  4. 如果存在一个针对 feature策略控制的功能,并且settings相关全局对象有一个关联的Document,则运行以下步骤:
    1. documentsettings相关全局对象关联的Document
    2. 如果 document允许使用 feature,则返回“denied”。
  5. key 为使用 settings描述符 生成权限密钥的结果。
  6. entry 为使用 描述符key 获取权限存储条目的结果。
  7. 如果 entry 不为 null,则从 entry状态返回一个 PermissionState 枚举值。
  8. 返回表示 feature 权限状态的 PermissionState 枚举值,同时考虑 描述符name 的任何权限状态约束

作为简写,一个 DOMString name权限状态权限状态,其PermissionDescriptorname 成员设置为name

5.2 请求使用强大功能的权限

请求使用权限一个描述符,用户代理必须执行以下步骤。 该算法返回"granted"或"denied"。

  1. current state成为描述符权限状态
  2. 如果current state不是"prompt", 返回current state并中止这些步骤。
  3. 请求用户提供明确权限,以允许调用算法使用 强大功能,该功能由描述符描述。
  4. 如果用户授予使用强大功能的明确许可,则将 current state 设置为“granted”; 否则设置为“denied”。 用户的交互可能会为提供关于用户意图的新信息
    注意

    此处故意对权限用户界面的细节以及用户代理如何推断用户意图保持模糊。用户代理应该能够在此框架内探索许多用户界面。

  5. key 为使用当前设置对象生成权限密钥的结果。
  6. 当前设置对象负责事件循环排队一个任务,以使用 descriptorkeycurrent state 设置权限存储条目
  7. 返回current state

作为简写,请求使用权限一个DOMString name,与请求使用权限一个PermissionDescriptor(其name成员设置为name)相同。

5.3 提示用户选择

提示用户选择与给定描述符关联的一个或多个选项,以及一个可选的布尔值 allowMultiple(默认为 false),用户代理必须执行以下步骤。此算法返回“denied”或用户的选择。

  1. 如果描述符权限状态为 "denied", 则返回"denied"并中止这些步骤。
  2. 如果描述符权限状态为 "granted",用户代理可以返回用户选择的一个(或多个,如果 allowMultiple为true)选项,并中止这些步骤。如果用户代理在不提示的情况下返回, 则后续对相同描述符和相同选项集的提示必须返回相同的选项, 除非用户代理收到了有关用户意图的新信息
  3. 请求用户选择一个或多个选项或拒绝权限,并等待他们选择:
    1. 如果调用算法指定了要在提示中包含的额外信息,请包括它。
    2. 如果allowMultiple为false,则限制为从选项中选择一个项; 否则,用户可以选择任意数量的选项。
  4. 如果用户选择了一个或多个选项,则返回它们;否则返回"denied"。
    注意

    该操作故意对权限UI的细节以及用户代理如何推断用户意图保持模糊。用户代理应能够在此框架内探索大量UI选项 (例如,权限提示可能会超时并自动返回"denied",而无需用户明确选择)。

作为简写,提示用户从DOMString name 关联的选项中进行选择,等同于提示用户从PermissionDescriptor(其 name 成员设置为 name)关联的那些选项中进行选择。

5.4 对用户撤销权限的反应

当用户代理得知用户不再打算授予使用描述符中描述的功能的权限,并且该功能是在由 PermissionDescriptor 中的key描述的上下文中时,通过执行以下步骤对用户撤销权限的操作

  1. 执行描述符name权限撤销算法
  2. 删除权限存储条目,包括描述符key

6. 权限 API

WebIDL[Exposed=(Window)]
partial interface Navigator {
  [SameObject] readonly attribute Permissions permissions;
};

[Exposed=(Worker)]
partial interface WorkerNavigator {
  [SameObject] readonly attribute Permissions permissions;
};

6.2 Permissions 接口

WebIDL[Exposed=(Window,Worker)]
interface Permissions {
  Promise<PermissionStatus> query(object permissionDesc);
};

dictionary PermissionDescriptor {
  required DOMString name;
};

6.2.1 query() 方法

当调用 query() 方法时,用户代理 必须运行以下查询权限算法,并传递参数 permissionDesc

  1. 如果 this相关全局对象是一个 Window 对象,则:
    1. 如果当前设置对象关联 Document 不是完全激活状态,则返回一个被拒绝的 promise,并带有一个“InvalidStateErrorDOMException
  2. rootDescpermissionDesc 指向的对象,并将其转换为 IDL 值,类型为 PermissionDescriptor
  3. 如果转换抛出一个异常,则返回一个被拒绝的 promise,并带有该异常。
  4. 如果 rootDesc["name"] 不受支持,则返回一个被拒绝的 promise,并带有一个 TypeError
    注意: 为什么这不是一个枚举?
  5. typedDescriptorpermissionDesc 指向的对象,并将其转换为 IDL 值,类型为 rootDescname权限描述符类型
  6. 如果转换抛出一个异常,则返回一个被拒绝的 promise,并带有该异常。
  7. promise一个新的 promise
  8. 返回 promise并行继续执行:
    1. status 为使用 typedDescriptor 创建一个 PermissionStatus
    2. querystatus[[query]] 内部插槽。
    3. 运行 queryname权限查询算法,并传递 querystatus
    4. 权限任务源上使用 this相关全局对象排队一个全局任务,以使用 status 解决 promise

6.3 PermissionStatus 接口

WebIDL[Exposed=(Window,Worker)]
interface PermissionStatus : EventTarget {
  readonly attribute PermissionState state;
  readonly attribute DOMString name;
  attribute EventHandler onchange;
};

enum PermissionState {
  "granted",
  "denied",
  "prompt",
};

PermissionStatus 实例会创建一个 [[query]] 内部槽, 它是某个特性的 权限描述符类型 的实例。

"granted"、"denied" 和 "prompt" 枚举值分别表示 "授予""拒绝""提示" 的概念。

6.3.1 创建实例

要为给定的 PermissionDescriptor permissionDesc 创建一个 PermissionStatus

  1. namepermissionDescname
  2. 断言:由 name 标识的 特性 由用户代理支持。
  3. status 为由 name 标识的 权限结果类型 的新实例:
    1. status[[query]] 内部槽初始化为 permissionDesc
    2. status name 初始化为 name
  4. 返回 status

6.3.2 name 属性

name 属性返回其初始化的值。

6.3.3 state 属性

state 属性返回在当前实例上设置的最新值。

6.3.4 onchange 属性

onchange 属性是一个事件处理程序,其对应的事件处理程序事件类型change

每当用户代理意识到 PermissionStatus 实例 status 的状态发生更改时,它会异步运行PermissionStatus 更新步骤

  1. 如果 this相关全局对象是一个 Window 对象,则:
    1. documentstatus相关全局对象关联 Document
    2. 如果 document 为 null 或者 document 不是完全激活状态, 则终止此算法。
  2. querystatus[[query]] 内部插槽。
  3. 运行 queryname权限查询算法,并传递 querystatus
  4. 权限任务源排队一个任务,以在 status触发一个名为 change 的事件

6.3.5 垃圾回收

如果一个 PermissionStatus 对象具有一个类型为 change事件侦听器,则该对象不得被垃圾回收。

7. 一致性

除了标记为非规范的部分外,本规范中的所有创作指南、图表、示例和注释均为非规范内容。本规范中的其他内容均为规范性内容。

本文件中的关键词 MAYMUSTMUST NOTOPTIONALSHOULD 应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释,仅当它们以全大写形式出现时,如本处所示。

两类产品可以声明符合本规范:用户代理以及其他规范(即,以符合本规范要求的方式指定强大功能的技术报告)。

A. 与权限策略规范的关系

本节为非规范性内容。

尽管本规范与 权限策略 规范都涉及“权限”,但每个规范在平台中都有独特的作用。 尽管如此,这两个规范确实存在明确的重叠。

一方面,本规范只关心通过用户代理权限UI管理访问的 强大功能 (即,用户在使用该功能前给予明确同意,并且用户可以随时以任何理由拒绝该权限的权限),这些强大功能已在 权限注册表 中注册。

另一方面,权限策略规范允许开发人员通过“权限策略”(无论是 HTTP 标头还是 allow 属性)选择性地启用和禁用策略控制的功能。从这个意义上说,权限策略包含了本规范,因为权限策略独立于本规范来决定某个功能是否可用。这些策略控制的功能也注册在权限注册表中。

一个被权限策略规范禁用的强大功能,其权限状态在本规范中始终反映为“拒绝”。 这是因为读取当前权限依赖于[HTML]的“允许使用”检查,而该检查本身会调用权限策略规范。 此处需要注意的重要一点是两个规范之间共享权限名称。本规范和权限策略规范都依赖于其他规范来定义权限的名称和名称,并且它们通常被命名为相同的东西(例如,地理位置的“geolocation”,等等)。

最后,通过 权限策略 规范,强大功能永远不可能被授予“granted”状态。 强大功能被 “授予” 的唯一方法是通过用户明确的权限或某些用户代理策略。

B. 自动化测试

为了用户代理自动化和应用程序测试的目的,本文档定义了对 [WebDriver] 和 [WebDriver-BiDi] 规范的扩展。用户代理支持它们是可选的

WebIDLdictionary PermissionSetParameters {
  required object descriptor;
  required PermissionState state;
};

为给定的 PermissionDescriptor descriptorPermissionState state、一个可选的 origin 和一个可选的 user agent 设置权限时:

  1. target origin当前设置对象(如果 origin 为 null),否则为 origin
  2. targets 为一个列表,其中包含所有环境设置对象,这些对象的target origin 同源,并且如果提供了 user agent,则属于该user agent,否则属于所有用户代理。
  3. tasks 为一个空的列表
  4. 对于 targets 中的每个环境设置对象 target
    1. target相关设置对象全局对象浏览上下文权限任务源排队一个任务 task,以执行以下步骤:
      1. state 解释为此刻使用参数 target 调用 descriptor权限状态的结果。
    2. task 附加tasks
  5. 等待 tasks 中的所有任务执行完毕并返回。

B.1 使用 [WebDriver] 进行自动化测试

本文档为 [WebDriver] 规范定义了以下扩展命令

B.1.1 设置权限

HTTP 方法 URI 模板
POST /session/{session id}/permissions

设置权限扩展命令模拟用户修改 PermissionDescriptor权限状态

远程端步骤如下:

  1. parametersDictparameters 参数,将其转换为 IDL 值,类型为 PermissionSetParameters。如果此操作抛出异常,则返回无效参数错误
  2. 如果由于任何实现定义的原因,parametersDict.state 是一个不适当的权限状态,则返回无效参数错误
    注意

    例如,将“midi”强大功能定义为“始终开启”的用户代理可以选择在此步骤拒绝将权限状态设置为“denied”的命令。

  3. rootDescparametersDict.descriptor
  4. typedDescriptorrootDesc 指向的对象,将其转换为 IDL 值,类型为与 Get(rootDesc, "name") 结果匹配的权限描述符类型。如果此操作抛出异常,则返回无效参数错误
  5. 使用 typedDescriptorparametersDict.state 设置权限
  6. 返回成功,数据为 null

B.2 使用 [WebDriver-BiDi] 进行自动化测试

本文档为 [WebDriver-BiDi] 规范定义了以下扩展模块

B.2.1 权限模块

权限模块包含管理远程端浏览器权限的命令。

B.2.1.1 定义

远程端定义

PermissionsCommand = (
          permissions.setPermission
        )
B.2.1.2 类型
B.2.1.2.1 permissions.PermissionDescriptor 类型
permissions.PermissionDescriptor = {
          name: text,
        }

permissions.PermissionDescriptor 类型表示 PermissionDescriptor

B.2.1.2.2 permissions.PermissionState 类型
permissions.PermissionState = "granted" / "denied" / "prompt"

permissions.PermissionState 类型表示 PermissionState

B.2.1.3 命令
B.2.1.3.1 permissions.setPermission 命令

设置权限命令模拟用户修改 PermissionDescriptor权限状态

命令类型
permissions.setPermission = (
          method: "permissions.setPermission",
          params: permissions.SetPermissionParameters
        )
        
        permissions.SetPermissionParameters = {
          descriptor: permissions.PermissionDescriptor,
          state: permissions.PermissionState,
          origin: text,
          ? userContext: text,
        }
返回类型
EmptyResult

使用 sessioncommand parameters远程端步骤如下:

  1. descriptorcommand parametersdescriptor 字段的值。
  2. permission namedescriptorname 字段的值,代表 name
  3. statecommand parametersstate 字段的值。
  4. user context idcommand parametersuserContext 字段的值(如果存在),否则为 default
  5. 如果由于任何实现定义的原因,state 是一个不适当的权限状态,则返回带有错误代码 invalid argument错误
  6. typedDescriptordescriptor 指向的对象,将 (descriptor, state) 转换为 IDL 值,类型为 PermissionSetParameters permission name权限描述符类型。如果此转换引发异常,则返回带有错误代码 invalid argument错误
  7. origincommand parametersorigin 字段的值。
  8. user agent 为代表 ID 为 user context id用户上下文用户代理
  9. 使用 typedDescriptorstateoriginuser agent 设置权限
  10. 返回带有数据 null成功

C. 权限注册表

本节为非规范性内容。

C.1 目的

这个 W3C 注册表提供了一个集中的位置,用于查找 Web 平台的策略控制功能和/或强大功能。通过变更过程,它还有助于确保平台中的权限在各种规范中得到一致的指定。

通过将注册表划分为标准化权限和临时权限,注册表还提供了一种方法来跟踪这些功能的状态。

C.2 更改过程

更改过程 用于添加或更新此注册表,步骤如下:

  1. 如果有必要,请在规范中添加“权限策略”部分,其中包括以下内容:
    1. 标识策略控制功能的字符串(例如,"super-awesome")。确保通过将其包装在 dfn 元素中使字符串可链接。
    2. 默认允许列表值(例如 'self')。
  2. 确定您的功能是否符合 强大功能的定义(即,需要明确许可才能使用)。 如果是:
    1. 在您的规范中指定强大功能,并符合 权限规范。
  3. 修改标准化权限表临时权限表,填写每一列所需的信息。
  4. GitHub 上的强大功能注册表存储库提交包含更改的 pull 请求。存储库的维护人员将审查您的 pull 请求,并检查所有内容是否正确集成。

C.3 标准化权限注册表

要使某个权限出现在标准化权限表中,并被认为是 标准化权限,需要满足以下标准:

每个权限都由一个唯一的文字字符串标识。对于权限策略,该字符串标识一个策略控制的功能。 类似地,在权限规范中,该字符串标识一个强大功能

注意: 权限和权限策略
Web 平台标准化权限表
标识字符串 策略控制的功能吗? 强大功能吗? 规范 实现
Chromium Gecko WebKit
"geolocation" Geolocation
"notifications" Notifications API Standard
"push" Push API
"web-share" Web Share API

C.4 临时权限注册表

临时权限是尚未 标准化 的权限 (即它们要么是实验性的,还处于孵化阶段,或者仅在单一浏览器引擎中实现)。

临时权限表
标识字符串 策略控制的功能吗? 强大功能吗? 规范 实现
Chromium Gecko WebKit
"accelerometer" 设备方向和运动
"window-management" 窗口管理
"local-fonts" 本地字体访问

D. 隐私注意事项

对手可能会利用权限状态作为创建用户“指纹”的元素。虽然对手已经可以通过实际使用 API 来确定权限状态,但这通常会导致向终端用户显示 UI 提示(如果权限尚未被“授予”)。虽然该 API 不会向网站暴露新的指纹信息,但它使对手更容易悄悄地访问这些信息。

用户代理应该提供一种方式,供用户审查、更新和重置与某个关联的强大功能权限状态

E. 安全注意事项

目前没有记录的安全注意事项。建议读者参考第D. 隐私注意事项部分。

F. IDL 索引

WebIDL[Exposed=(Window)]
partial interface Navigator {
  [SameObject] readonly attribute Permissions permissions;
};

[Exposed=(Worker)]
partial interface WorkerNavigator {
  [SameObject] readonly attribute Permissions permissions;
};

[Exposed=(Window,Worker)]
interface Permissions {
  Promise<PermissionStatus> query(object permissionDesc);
};

dictionary PermissionDescriptor {
  required DOMString name;
};

[Exposed=(Window,Worker)]
interface PermissionStatus : EventTarget {
  readonly attribute PermissionState state;
  readonly attribute DOMString name;
  attribute EventHandler onchange;
};

enum PermissionState {
  "granted",
  "denied",
  "prompt",
};

dictionary PermissionSetParameters {
  required object descriptor;
  required PermissionState state;
};

G. 致谢

本节为非规范性部分。

编辑们感谢 Adrienne Porter Felt、Anne van Kesteren、Domenic Denicola、Jake Archibald 和 Wendy Seltzer 对 API 设计和编辑工作的帮助。

H. 参考文献

H.1 规范性参考文献

[dom]
DOM 标准。Anne van Kesteren。WHATWG。现行标准。URL:https://dom.spec.whatwg.org/
[ecma-262]
ECMAScript 语言规范。Ecma International。URL:https://tc39.es/ecma262/multipage/
[HTML]
HTML 标准。由 Anne van Kesteren、Domenic Denicola、Dominic Farolino、Ian Hickson、Philip Jägenstedt、Simon Pieters 编著。WHATWG。动态标准。网址:https://html.spec.whatwg.org/multipage/
[infra]
基础标准。Anne van Kesteren; Domenic Denicola。WHATWG。现行标准。URL:https://infra.spec.whatwg.org/
[Notifications]
通知 API 标准。Anne van Kesteren。WHATWG。现行标准。URL:https://notifications.spec.whatwg.org/
[Permissions-Policy]
权限策略。Ian Clelland。W3C。2024年9月25日。W3C 工作草案。网址:https://www.w3.org/TR/permissions-policy-1/
[permissions-registry]
权限注册表。W3C。草案注册表。URL:https://w3c.github.io/permissions-registry/
[RFC2119]
RFC 中指示要求级别的关键词。S. Bradner。IETF。1997 年 3 月。最佳现行规范。URL:https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 中大写与小写模糊性。B. Leiba。IETF。2017 年 5 月。最佳现行规范。URL:https://www.rfc-editor.org/rfc/rfc8174
[WebDriver]
WebDriver。Simon Stewart; David Burns。W3C。2018 年 6 月 5 日。W3C 推荐标准。URL:https://www.w3.org/TR/webdriver1/
[WebDriver-BiDi]
WebDriver BiDi。由 James Graham、Alex Rudenko、Maksim Sadym 编著。W3C。2024年12月6日。W3C 工作草案。网址:https://www.w3.org/TR/webdriver-bidi/
[webdriver2]
WebDriver。由 Simon Stewart、David Burns 编著。W3C。2024年12月12日。W3C 工作草案。网址:https://www.w3.org/TR/webdriver2/
[WEBIDL]
Web IDL 标准。Edgar Chen; Timothy Gu。WHATWG。现行标准。URL:https://webidl.spec.whatwg.org/

H.2 参考性文献

[appmanifest]
Web 应用程序清单。由 Marcos Caceres、Kenneth Christiansen、Diego Gonzalez-Zuniga、Daniel Murphy、Christian Liebel 编著。W3C。2024年11月7日。W3C 工作草案。网址:https://www.w3.org/TR/appmanifest/
[Geolocation]
地理位置。由 Marcos Caceres、Reilly Grant 编著。W3C。2024年9月16日。W3C 推荐标准。网址:https://www.w3.org/TR/geolocation/
[GETUSERMEDIA]
媒体捕获和流。由 Cullen Jennings、Bernard Aboba、Jan-Ivar Bruaroey、Henrik Boström、youenn fablet 编著。W3C。2024年12月5日。W3C 候选推荐标准。网址:https://www.w3.org/TR/mediacapture-streams/
[local-font-access]
本地字体访问。WICG。社区组草案。网址:https://wicg.github.io/local-font-access/
[orientation-event]
设备方向和运动。由 Marcos Caceres、Reilly Grant 编著。W3C。2024年11月21日。W3C 候选推荐标准。网址:https://www.w3.org/TR/orientation-event/
[Permissions]
权限。由 Marcos Caceres、Mike Taylor 编著。W3C。2024年3月19日。W3C 工作草案。网址:https://www.w3.org/TR/permissions/
[push-api]
推送 API。由 Peter Beverloo、Martin Thomson、Marcos Caceres 编著。W3C。2024年9月3日。W3C 工作草案。网址:https://www.w3.org/TR/push-api/
[w3c-process]
W3C 流程文档。由 Elika J. Etemad (fantasai)、Florian Rivoal 编著。W3C。2023年11月3日。网址:https://www.w3.org/policies/process/
[Web-Share]
Web 分享 API。由 Matt Giuca、Eric Willigers、Marcos Caceres 编著。W3C。2023年5月30日。W3C 推荐标准。网址:https://www.w3.org/TR/web-share/
[window-management]
窗口管理。由 Joshua Bell、Mike Wasserman 编著。W3C。2024年6月7日。W3C 工作草案。网址:https://www.w3.org/TR/window-management/