webRequest.onAuthRequired

当服务器发送 401407 状态码以及使用 Basic 方案的 WWW-Authenticate 标头时触发(即,当服务器要求客户端提供身份验证凭据,例如用户名和密码时)。

侦听器可以通过四种方式响应

不采取任何操作

侦听器可以什么都不做,只是观察请求。如果发生这种情况,它不会影响请求的处理,并且浏览器会在适当情况下提示用户登录。

取消请求

侦听器可以取消请求。如果这样做,身份验证将失败,并且不会提示用户登录。扩展可以通过以下方式取消请求

  • 在 addListener 中,在 extraInfoSpec 参数中传递 "blocking"
  • 在侦听器中,返回一个对象,其中 cancel 属性设置为 true
同步提供凭据

如果凭据可以同步获取,则扩展可以同步提供它们。如果扩展这样做,浏览器将尝试使用这些凭据登录。侦听器可以通过以下方式同步提供凭据

  • 在 addListener 中,在 extraInfoSpec 参数中传递 "blocking"
  • 在侦听器中,返回一个对象,其中 authCredentials 属性设置为要提供的凭据
异步提供凭据

扩展可能需要异步获取凭据。例如,扩展可能需要从存储中获取凭据或询问用户。在这种情况下,侦听器可以通过以下方式异步提供凭据

  • 在 addListener 中,在 extraInfoSpec 参数中传递 Chrome 和 Firefox 中的 "asyncBlocking" 或 Firefox 中的 "blocking"
  • 如果提供了 "blocking",则扩展可以返回 webRequest.BlockingResponse 对象或解析为 webRequest.BlockingResponse 对象的 Promise
  • 如果提供了 "asyncBlocking",则事件侦听器函数将其第二个参数作为 asyncCallback 函数接收。asyncCallback 可以异步调用,并以 webRequest.BlockingResponse 对象作为其唯一参数

    注意:Chrome 不支持 Promise 作为返回值(Chromium 问题 1510405)。有关替代方法,请参阅 listener 的返回值

请参阅 示例

如果您的扩展提供了错误的凭据,则会再次调用侦听器。因此,请注意避免通过重复提供错误的凭据进入无限循环。

权限

在 Firefox 和 Chrome 清单 V2 扩展中,您必须将 "webRequest""webRequestBlocking" API 权限 添加到您的 manifest.json 中。

对于清单 V3 扩展,Chrome 不再支持 "webRequestBlocking" 权限(策略安装的扩展除外)。相反,"webRequest""webRequestAuthProvider" 权限使您能够异步提供凭据。Firefox 在清单 V3 中继续支持 "webRequestBlocking",并提供 "webRequestAuthProvider" 以提供跨浏览器兼容性。

代理授权

Firefox 通常不会为系统请求(例如浏览器或扩展升级或搜索引擎查询)触发 webRequest 事件。为了使代理授权能够平滑地适用于系统请求,从 57 版开始,Firefox 支持对此的例外。

如果扩展具有 "webRequest""webRequestBlocking""proxy""<all_urls>" 权限,则它可以使用 onAuthRequired 为代理授权提供凭据(但不能用于正常的 Web 授权)。侦听器不能取消系统请求或对任何系统请求进行任何其他修改。

语法

js
browser.webRequest.onAuthRequired.addListener(
  listener,                    // function
  filter,                      //  object
  extraInfoSpec                //  optional array of strings
)
browser.webRequest.onAuthRequired.removeListener(listener)
browser.webRequest.onAuthRequired.hasListener(listener)

事件具有三个函数

addListener(listener, filter, extraInfoSpec)

向此事件添加侦听器。

removeListener(listener)

停止侦听此事件。listener 参数是要移除的侦听器。

hasListener(listener)

检查 listener 是否为此事件注册。如果正在侦听,则返回 true,否则返回 false

addListener 语法

参数

listener

当此事件发生时调用的函数。该函数将传递以下参数

details

object。有关请求的详细信息。有关更多信息,请参阅 details 部分。

asyncCallback 可选

最多调用一次以异步修改请求对象的函数。此参数仅在使用 extraInfoSpec 数组中 "asyncBlocking" 注册事件侦听器时存在。如果未提供 extraInfoSpec 或包含 "blocking",则 asyncCallback 未定义。

返回值:webRequest.BlockingResponsePromise,具体取决于 extraInfoSpec 中的设置。

filter

webRequest.RequestFilter。限制发送到此侦听器的事件的过滤器。

extraInfoSpec 可选

stringarray。事件的其他选项。您可以传递以下任何值

  • "blocking":使请求阻塞,以便您可以取消请求或提供身份验证凭据。返回一个 BlockingResponse 对象,并设置其 cancelauthCredentials 属性。
    • 在 Chrome 中,事件侦听器必须同步响应。
    • 在 Firefox 中,事件侦听器可以同步响应或返回一个解析为 BlockingResponse 对象的 promise 以异步响应。
  • "asyncBlocking":异步处理请求。事件侦听器的返回值将被忽略。要解决事件,请将 asyncCallback 参数传递给 BlockingResponse 对象。
    • Chrome 120 和 Firefox 128 及更高版本支持。
    • Safari 不支持。

其他对象

details

challenger

object。请求身份验证的服务器。这是一个具有以下属性的对象

host

string。服务器的 主机名

port

integer。服务器的端口号。

cookieStoreId

string。如果请求来自在上下文身份中打开的标签页,则为上下文身份的 cookie 存储 ID。有关更多信息,请参阅 使用上下文身份

frameId

整数。如果请求发生在主框架中,则为0;正值是发生请求的子框架的 ID。如果(子)框架的文档被加载(typemain_framesub_frame),则frameId 指示此框架的 ID,而不是外部框架的 ID。框架 ID 在一个选项卡内是唯一的。

incognito

布尔值。请求是否来自隐私浏览窗口。

isProxy

布尔值Proxy-AuthenticatetrueWWW-Authenticatefalse

注意:webRequest.onAuthRequired 仅在需要身份验证的 HTTP 和 HTTPS/TLS 代理服务器上调用,不适用于需要身份验证的 SOCKS 代理服务器。

method

字符串。标准 HTTP 方法(例如,"GET""POST")。

parentFrameId

整数。包含发送请求的框架的框架的 ID。如果不存在父框架,则设置为-1

proxyInfo

对象。此属性仅在请求被代理时存在。它包含以下属性

host

字符串。代理服务器的主机名。

port

整数。代理服务器的端口号。

type

字符串。代理服务器的类型。以下之一:

  • "http":HTTP 代理(或 HTTPS 的 SSL CONNECT)
  • "https":通过到代理的 TLS 连接进行 HTTP 代理
  • "socks":SOCKS v5 代理
  • "socks4":SOCKS v4 代理
  • "direct":无代理
  • "unknown":未知代理
username

字符串。代理服务的用户名。

proxyDNS

布尔值。如果代理根据提供的主机名执行域名解析,则为真,这意味着客户端不应执行自己的 DNS 查找。

failoverTimeout

整数。故障转移超时时间(以秒为单位)。如果连接在这么多秒后仍无法连接到代理服务器,则使用从 FindProxyForURL() 返回的数组中的下一个代理服务器。

realm 可选

字符串。服务器提供的身份验证 领域(如果存在)。

requestId

字符串。请求的 ID。请求 ID 在浏览器会话中是唯一的,因此您可以关联与同一请求相关的不同事件。

responseHeaders 可选

webRequest.HttpHeaders。与此响应一起接收的 HTTP 响应标头。

scheme

字符串。身份验证方案:"basic""digest"。

statusCode

整数。服务器返回的标准 HTTP 状态代码。

statusLine

字符串。响应的 HTTP 状态行,对于 HTTP/0.9 响应(即缺少状态行的响应),为 'HTTP/0.9 200 OK' 字符串,如果不存在标头,则为空字符串。

tabId

整数。请求发生所在的选项卡的 ID。如果请求与选项卡无关,则设置为-1

thirdParty

布尔值。指示请求及其内容窗口层次结构是否为第三方。

timeStamp

数字。此事件触发的时刻,以 自纪元以来的毫秒数 为单位。

type

webRequest.ResourceType。正在请求的资源类型:例如,"image""script""stylesheet"

url

字符串。请求的目标。

urlClassification

对象。如果请求被 Firefox 跟踪保护 分类,则为与请求关联的跟踪类型。这是一个具有以下属性的对象

firstParty

字符串数组。请求的第一方的分类标志。

thirdParty

字符串数组。请求或其窗口层次结构的第三方的分类标志。

分类标志包括

  • fingerprintingfingerprinting_content:指示请求参与指纹识别(“发现可用于指纹识别的来源”)。
    • fingerprinting 指示该域名属于指纹识别和跟踪类别。此类域名的示例包括想要将个人资料与访问用户关联的广告客户。
    • fingerprinting_content 指示该域名属于指纹识别类别,但不属于跟踪类别。此类域名的示例包括使用指纹识别技术识别访问用户以进行反欺诈的支付提供商。
  • cryptominingcryptomining_content:与指纹识别类别类似,但用于加密挖矿资源。
  • trackingtracking_adtracking_analyticstracking_socialtracking_content:指示请求参与跟踪。tracking 是任何通用的跟踪请求。adanalyticssocialcontent 后缀标识跟踪器的类型。
  • any_basic_tracking:一个元标志,结合了跟踪和指纹识别标志,不包括 tracking_contentfingerprinting_content
  • any_strict_tracking:一个元标志,结合了所有跟踪和指纹识别标志。
  • any_social_tracking:一个元标志,结合了所有社交跟踪标志。

示例

此代码观察目标 URL 的身份验证请求

js
const target = "https://intranet.company.com/";

function observe(requestDetails) {
  console.log(`observing: ${requestDetails.requestId}`);
}

browser.webRequest.onAuthRequired.addListener(observe, { urls: [target] });

此代码取消目标 URL 的身份验证请求

js
const target = "https://intranet.company.com/";

function cancel(requestDetails) {
  console.log(`canceling: ${requestDetails.requestId}`);
  return { cancel: true };
}

browser.webRequest.onAuthRequired.addListener(cancel, { urls: [target] }, [
  "blocking",
]);

此代码同步提供凭据。它跟踪未完成的请求,以确保不会重复尝试提交错误的凭据

js
const target = "https://intranet.company.com/";

const myCredentials = {
  username: "[email protected]",
  password: "zDR$ERHGDFy",
};

const pendingRequests = [];

// A request has completed.
// We can stop worrying about it.
function completed(requestDetails) {
  console.log(`completed: ${requestDetails.requestId}`);
  let index = pendingRequests.indexOf(requestDetails.requestId);
  if (index > -1) {
    pendingRequests.splice(index, 1);
  }
}

function provideCredentialsSync(requestDetails) {
  // If we have seen this request before, then
  // assume our credentials were bad, and give up.
  if (pendingRequests.includes(requestDetails.requestId)) {
    console.log(`bad credentials for: ${requestDetails.requestId}`);
    return { cancel: true };
  }
  pendingRequests.push(requestDetails.requestId);
  console.log(`providing credentials for: ${requestDetails.requestId}`);
  return { authCredentials: myCredentials };
}

browser.webRequest.onAuthRequired.addListener(
  provideCredentialsSync,
  { urls: [target] },
  ["blocking"],
);

browser.webRequest.onCompleted.addListener(completed, { urls: [target] });

browser.webRequest.onErrorOccurred.addListener(completed, { urls: [target] });

此代码异步提供凭据,从存储中获取它们。它还跟踪未完成的请求,以确保不会重复尝试提交错误的凭据

js
const target = "https://httpbin.org/basic-auth/*";

const pendingRequests = [];

/*
 * A request has completed. We can stop worrying about it.
 */
function completed(requestDetails) {
  console.log(`completed: ${requestDetails.requestId}`);
  let index = pendingRequests.indexOf(requestDetails.requestId);
  if (index > -1) {
    pendingRequests.splice(index, 1);
  }
}

function provideCredentialsAsync(requestDetails) {
  // If we have seen this request before,
  // then assume our credentials were bad,
  // and give up.
  if (pendingRequests.includes(requestDetails.requestId)) {
    console.log(`bad credentials for: ${requestDetails.requestId}`);
    return { cancel: true };
  } else {
    pendingRequests.push(requestDetails.requestId);
    console.log(`providing credentials for: ${requestDetails.requestId}`);
    // we can return a promise that will be resolved
    // with the stored credentials
    return browser.storage.local.get(null);
  }
}

browser.webRequest.onAuthRequired.addListener(
  provideCredentialsAsync,
  { urls: [target] },
  ["blocking"],
);

browser.webRequest.onCompleted.addListener(completed, { urls: [target] });

browser.webRequest.onErrorOccurred.addListener(completed, { urls: [target] });

扩展示例

浏览器兼容性

BCD 表格仅在浏览器中加载

注意:此 API 基于 Chromium 的 chrome.webRequest API。此文档源自 Chromium 代码中的 web_request.json