权限

与强大功能的权限交互

W3C工作草案

更多关于此文档的细节
此版本:
https://www.w3.org/TR/2024/WD-permissions-20240319/
最新发布版本:
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 logo122
Android Firefox logo123
Android UC logo15.5
iOS Safari logo16.0
Samsung Internet logo4
移动版
更多信息

摘要

本规范定义了其他规范可以用来与浏览器权限交互的通用基础设施。这些权限代表用户对平台“强大功能”访问的允许或拒绝选择。对于开发人员来说,本规范标准化了一个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();
    
    // 过滤视频输入,并映射到查询对象
    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);
      // 记录每个摄像头的状态
      results.forEach(({ state }, i) => console.log("摄像头", i, state));
    } catch (error) {
      console.error(error);
    }

3. 模型

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

3.1 权限

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

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

注意:限制和可扩展性

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

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

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

注意:隐式信号是什么?

每个权限都有一个生命周期,这是指特定权限保持"授予"状态的持续时间,直到恢复到其默认状态。生命周期可以是直到特定Realm被销毁、特定顶层浏览上下文被销毁、特定时间段或无限期。生命周期由最终用户和用户代理协商,当用户通过某些权限UI或用户代理定义的策略授予明确权限使用某个功能时,通常进行此协商。

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

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标准),大多数强大功能也是策略控制的功能。对于同时是策略控制的功能的强大功能,[Permissions-Policy]控制文档是否被允许使用某个功能。也就是说,只有在通过相应的策略控制的功能将权限委派给文档时,强大功能才能向用户请求明确权限。后续对功能的访问由用户"授予"权限或满足相当于权限授予的条件决定。

一个强大功能由其名称标识,即一个字符串字面量(例如,"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. 返回与UA对用户意图的印象相匹配的name额外权限数据类型的实例,并考虑到name的任何额外权限数据约束

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

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

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

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

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

功能使用的权限键的类型。默认值为来源。指定了自定义权限键类型的功能必须还指定一个权限键生成算法

权限键生成算法

接收一个环境设置对象, 并返回一个新的权限键。如果未指定,则默认使用默认权限键生成算法。指定自定义权限键生成算法的功能必须还指定一个权限键比较算法

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

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

接收两个权限键并返回一个布尔值,显示两个键是否相等。如果未指定, 则默认使用默认权限键比较算法

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

  1. 返回key1key2是否为相同来源
权限撤销算法

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

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

权限生命周期

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

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

  1. 将权限恢复为其默认权限状态(例如,设置为“提示”)。
  2. 对于与该来源关联的每个browsing context(如果有),在队列中添加一个全局任务, 使用browsing context全局对象 来运行权限撤销算法
注意:确定权限生命周期
默认权限状态

一个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相关的全局对象 具有一个关联的文档,则执行以下步骤:
    1. document设为settings相关的全局对象关联文档
    2. 如果document不被允许使用 feature,则返回"denied"。
  5. key成为生成权限密钥的结果,用于 描述符settings
  6. entry成为获取权限存储条目的结果,带有 描述符key
  7. 如果entry不为null,返回entryPermissionState 枚举值来自entry状态
  8. 返回代表feature权限状态的 PermissionState 枚举值,考虑到任何描述符权限状态限制

简写形式为,DOMStringname权限状态权限状态PermissionDescriptor带有其 name 成员设为name

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

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

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

    该操作故意对权限UI的细节以及用户代理如何推断用户意图保持模糊。用户代理应能够在此框架内探索大量UI选项。

  5. key成为生成权限密钥的结果,使用 当前设置对象
  6. 在任务队列中, 将描述符keycurrent 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,并带有 "InvalidStateError" DOMException
  2. rootDesc 设为 permissionDesc 指向的对象,转换为 IDL 值 类型为 PermissionDescriptor
  3. 如果转换 抛出异常,则返回 一个被拒绝的 promise,并带有该异常。
  4. 如果 rootDesc["name"] 不被支持,则返回 一个被拒绝的 promise,并带有 TypeError
    注意: 为什么这不是一个枚举?
  5. typedDescriptor 设为 permissionDesc 指向的对象,转换为 IDL 值 类型为 rootDescname权限描述符类型
  6. 如果转换 抛出异常,则返回 一个被拒绝的 promise,并带有该异常。
  7. promise 设为 一个新的 promise
  8. 返回 promise 并在 并行 中继续:
    1. 使用 typedDescriptor 创建一个 PermissionStatus
    2. query 设为 status[[query]] 内部插槽。
    3. 运行 queryname权限查询算法,并传递 querystatus
    4. 在权限任务源上排队一个全局任务,并使用 this相关全局对象解析 promise 并返回 status

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. document 成为 status相关全局对象关联的 Document
    2. 如果 document 为 null 或 document完全激活, 终止此算法。
  2. query 成为 status[[query]] 内部槽。
  3. 运行 queryname权限查询算法,传递 querystatus
  4. 队列任务权限任务源 上,以 触发一个事件, 名为 change,在 status 上。

6.3.5 垃圾回收

如果 PermissionStatus 对象有类型为 change事件监听器, 则 不得 将其进行垃圾回收。

7. 一致性

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

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

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

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

本节为非规范性内容。

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

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

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

权限策略 禁用的强大功能在本规范中总是反映为 权限状态 为“denied”。 这是因为 读取当前权限状态 依赖于 [HTML] 中的“允许使用”检查, 该检查本身调用了 权限策略 规范。 这里需要注意的是在两个规范中共享权限名称。本规范和 权限策略 规范都依赖于其他规范来定义权限名称, 并且它们通常名称相同(例如,地理定位 API 中的“geolocation”等)。

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

B. 自动化测试

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

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

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

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

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

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

B.1.1 设置权限

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

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

远程端步骤如下:

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

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

  3. rootDescparametersDict.descriptor
  4. typedDescriptorrootDesc 所引用的对象,转换为与通过 获取(rootDesc,"name") 结果匹配的 权限描述符类型的 IDL 值。如果此转换抛出异常,返回 无效参数 错误
  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 命令

Set Permission 命令 模拟用户修改 PermissionDescriptorpermission state

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

远程端步骤sessioncommand parameters 如下:

  1. descriptor 设为 command parametersdescriptor 字段的值。
  2. permission name 设为 descriptorname 字段的值,代表 name
  3. state 设为 command parametersstate 字段的值。
  4. user context id 设为 command parametersuserContext 字段的值(如果存在),否则为 default
  5. 如果 state 是不适当的 permission state,则返回带有 错误错误代码无效参数
  6. typedDescriptor 设为 descriptor 所引用的对象,转换为 IDL 值 (descriptor, state),对应 权限描述符类型。如果此转换引发异常,则返回带有 错误无效参数
  7. origin 设为 command parametersorigin 字段的值。
  8. user agent 设为代表带有 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 API
"notifications" Notifications API Standard
"push" Push API
"web-share" Web Share API

C.4 临时权限注册表

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

临时权限表
标识字符串 是否为 策略控制功能 是否为 强大功能 规范 实现情况
Chromium Gecko WebKit
"accelerometer" DeviceOrientation 事件规范
"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; Ian Hickson; Philip Jägenstedt; Simon Pieters。WHATWG。现行标准。URL: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。2023 年 12 月 18 日。W3C 工作草案。URL: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。W3C。编辑草案。URL:https://w3c.github.io/webdriver-bidi/
[webdriver2]
WebDriver。Simon Stewart; David Burns。W3C。2024 年 1 月 23 日。W3C 工作草案。URL: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; Matt Giuca; Aaron Gustafson; Daniel Murphy; Anssi Kostiainen。W3C。2023 年 11 月 29 日。W3C 工作草案。URL:https://www.w3.org/TR/appmanifest/
[Geolocation]
地理位置 API。Marcos Caceres; Reilly Grant。W3C。2022 年 9 月 1 日。W3C 推荐标准。URL:https://www.w3.org/TR/geolocation/
[GETUSERMEDIA]
媒体捕获与流。Cullen Jennings; Bernard Aboba; Jan-Ivar Bruaroey; Henrik Boström; youenn fablet。W3C。2023 年 11 月 20 日。W3C 候选推荐标准。URL:https://www.w3.org/TR/mediacapture-streams/
[local-font-access]
本地字体访问。WICG。社区草案。URL:https://wicg.github.io/local-font-access/
[orientation-event]
设备方向事件规范。Reilly Grant; Raphael Kubo da Costa。W3C。2024 年 2 月 2 日。W3C 工作草案。URL:https://www.w3.org/TR/orientation-event/
[Permissions]
权限。Marcos Caceres; Mike Taylor。W3C。2024 年 1 月 16 日。W3C 工作草案。URL:https://www.w3.org/TR/permissions/
[push-api]
推送 API。Peter Beverloo; Martin Thomson; Marcos Caceres。W3C。2023 年 12 月 11 日。W3C 工作草案。URL:https://www.w3.org/TR/push-api/
[w3c-process]
W3C 过程文档。Elika J. Etemad (fantasai); Florian Rivoal。W3C。2021 年 11 月 2 日。URL:https://www.w3.org/Consortium/Process/
[Web-Share]
Web 分享 API。Matt Giuca; Eric Willigers; Marcos Caceres。W3C。2023 年 5 月 30 日。W3C 推荐标准。URL:https://www.w3.org/TR/web-share/
[window-management]
窗口管理。Joshua Bell; Mike Wasserman。W3C。2023 年 9 月 6 日。W3C 工作草案。URL:https://www.w3.org/TR/window-management/