webRequest.onAuthRequired
当服务器发送 401 或 407 状态码并使用 Basic 方案的 WWW-Authenticate 头时(即服务器要求客户端提供身份验证凭据,例如用户名和密码时),此事件被触发。
监听器可以以以下四种方式之一响应:
- 不采取任何行动
-
监听器可以不做任何事情,只是观察请求。如果发生这种情况,它不会影响请求的处理,并且浏览器会酌情要求用户登录。
- 取消请求
-
监听器可以取消请求。如果这样做,身份验证将失败,并且不会要求用户登录。扩展可以通过以下方式取消请求:
- 在 addListener 中,在
extraInfoSpec参数中传入"blocking" - 在监听器中,返回一个带有
cancel属性并设置为true的对象
- 在 addListener 中,在
- 同步提供凭据
-
如果凭据可以同步获取,扩展可以同步提供它们。如果扩展这样做,浏览器会尝试使用这些凭据登录。监听器可以通过以下方式同步提供凭据:
- 在 addListener 中,在
extraInfoSpec参数中传入"blocking" - 在监听器中,返回一个带有
authCredentials属性并设置为要提供的凭据的对象
- 在 addListener 中,在
- 异步提供凭据
-
扩展可能需要异步获取凭据。例如,扩展可能需要从存储中获取凭据或询问用户。在这种情况下,监听器可以通过以下方式异步提供凭据:
-
在 addListener 中,在
extraInfoSpec参数中传入 Chrome 和 Firefox 中的"asyncBlocking"或 Firefox 中的"blocking" -
如果提供了
"blocking",扩展可以返回一个webRequest.BlockingResponse对象或一个解析为webRequest.BlockingResponse对象的 Promise -
如果提供了
"asyncBlocking",事件监听函数将接收一个asyncCallback函数作为其第二个参数。asyncCallback可以异步调用,并接受一个webRequest.BlockingResponse对象作为其唯一参数注意:Chrome 不支持 Promise 作为返回值(Chromium 问题 1510405)。有关替代方案,请参阅
listener的返回值。
-
请参阅示例。
如果您的扩展提供错误的凭据,那么监听器将再次被调用。因此,请注意避免通过重复提供错误的凭据而进入无限循环。
Permissions
在 Firefox 和 Chrome Manifest V2 扩展中,您必须将"webRequest" 和 "webRequestBlocking" API 权限添加到您的 manifest.json 中。
对于 Manifest V3 扩展,Chrome 不再支持 "webRequestBlocking" 权限(策略安装的扩展除外)。相反,"webRequest" 和 "webRequestAuthProvider" 权限允许您异步提供凭据。Firefox 继续支持 Manifest V3 中的 "webRequestBlocking" 并提供 "webRequestAuthProvider" 以提供跨浏览器兼容性。
代理授权
Firefox 通常不会为系统请求(例如浏览器或扩展升级或搜索引擎查询)触发 webRequest 事件。为了使代理授权能够顺利地用于系统请求,从版本 57 开始,Firefox 支持一个例外。
如果扩展具有 "webRequest"、"webRequestBlocking"、"proxy" 和 "<all_urls>" 权限,那么它可以使用 onAuthRequired 为代理授权提供凭据(但不能用于正常的网络授权)。监听器不能取消系统请求或对任何系统请求进行任何其他修改。
语法
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 语法
参数
监听器-
此事件发生时调用的函数。该函数会传递以下参数:
details-
object。有关请求的详细信息。有关更多信息,请参阅 details 部分。 asyncCallback可选-
一个最多调用一次的函数,用于异步修改请求对象。此参数仅在事件监听器使用
extraInfoSpec数组中的"asyncBlocking"注册时才存在。如果未提供extraInfoSpec或包含"blocking",则asyncCallback未定义。
返回:
webRequest.BlockingResponse或Promise,具体取决于extraInfoSpec中的设置。 filter-
webRequest.RequestFilter。一个限制发送到此监听器的事件的过滤器。 extraInfoSpec可选-
array类型的string。事件的额外选项。您可以传递以下任何值:-
"blocking":使请求阻塞,以便您可以取消请求或提供身份验证凭据。返回一个BlockingResponse对象,并设置其cancel或authCredentials属性。- 在 Chrome 中,事件监听器必须同步响应。
- 在 Firefox 中,事件监听器可以同步响应或返回一个解析为
BlockingResponse对象的 Promise 以异步响应。
-
"asyncBlocking":异步处理请求。事件监听器的返回值将被忽略。要解决事件,请将asyncCallback参数传递一个BlockingResponse对象。- Chrome 120 和 Firefox 128 开始支持。
- Safari 不支持。
-
额外对象
details
challenger-
object。请求身份验证的服务器。这是一个包含以下属性的对象: -
string。如果请求来自上下文身份中打开的标签页,则为上下文身份的 cookie 存储 ID。有关更多信息,请参阅使用上下文身份。 frameId-
integer。如果请求发生在主框架中,则为0;正值表示请求发生的子框架的 ID。如果加载了(子)框架的文档(type为main_frame或sub_frame),frameId表示此框架的 ID,而不是外部框架的 ID。框架 ID 在一个标签页内是唯一的。 incognito-
boolean。请求是否来自隐私浏览窗口。 isProxy-
boolean。对于Proxy-Authenticate为true,对于WWW-Authenticate为false。注意:
webRequest.onAuthRequired仅在需要身份验证的 HTTP 和 HTTPS/TLS 代理服务器上调用,而不在需要身份验证的 SOCKS 代理服务器上调用。 method(方法)-
string。标准 HTTP 方法(例如,"GET"或"POST")。 parentFrameId-
integer。包含发送请求的框架的框架的 ID。如果没有父框架,则设置为-1。 proxyInfo-
object。此属性仅在请求通过代理时存在。它包含以下属性:主机-
string。代理服务器的主机名。 port-
integer。代理服务器的端口号。 type-
string。代理服务器的类型。以下之一:"http":HTTP 代理(或 HTTPS 的 SSL CONNECT)"https":通过 TLS 连接到代理的 HTTP 代理"socks":SOCKS v5 代理"socks4":SOCKS v4 代理"direct":无代理"unknown":未知代理
username-
string。代理服务的用户名。 proxyDNS-
boolean。如果代理根据提供的主机名执行域名解析,则为 True,这意味着客户端不应自行进行 DNS 查找。 failoverTimeout-
integer。故障转移超时(秒)。如果连接在此秒数后未能连接到代理服务器,则使用从FindProxyForURL()返回的数组中的下一个代理服务器。
realm可选-
string。如果存在,服务器提供的身份验证领域。 requestId-
string。请求的 ID。请求 ID 在浏览器会话中是唯一的,因此您可以关联与同一请求相关的不同事件。 responseHeaders可选-
webRequest.HttpHeaders。此响应收到的 HTTP 响应头。 scheme-
string。身份验证方案:"basic"或"digest"。 statusCode-
integer。服务器返回的标准 HTTP 状态码。 statusLine-
string。响应的 HTTP 状态行,HTTP/0.9 响应的'HTTP/0.9 200 OK'字符串(即缺少状态行的响应),如果没有任何头,则为空字符串。 tabId-
integer。请求发生的标签页的 ID。如果请求与标签页无关,则设置为-1。 thirdParty-
boolean。指示请求及其内容窗口层次结构是否是第三方。 timeStamp-
number。此事件触发的时间,以纪元以来的毫秒数表示。 type-
webRequest.ResourceType。正在请求的资源的类型:例如,"image"、"script"或"stylesheet"。 url-
string。请求的目标。 urlClassification-
object。如果请求被Firefox 跟踪保护分类,则与请求关联的跟踪类型。这是一个包含以下属性的对象:firstParty-
array类型的string。请求的第一方分类标志。 thirdParty-
array类型的string。请求或其窗口层次结构的第三方分类标志。
分类标志包括:
fingerprinting和fingerprinting_content:表示请求涉及指纹识别(“发现指纹识别的来源”)。fingerprinting表示该域属于指纹识别和跟踪类别。此类域的示例包括希望将配置文件与访问用户关联的广告商。fingerprinting_content表示该域属于指纹识别类别但不属于跟踪类别。此类域的示例包括使用指纹识别技术识别访问用户以进行反欺诈目的的支付提供商。
cryptomining和cryptomining_content:类似于指纹识别类别,但用于加密挖矿资源。tracking、tracking_ad、tracking_analytics、tracking_social和tracking_content:表示请求涉及跟踪。tracking是任何通用跟踪请求。ad、analytics、social和content后缀标识跟踪器的类型。emailtracking和emailtracking_content:表示请求涉及跟踪电子邮件。any_basic_tracking:一个元标志,结合了跟踪和指纹识别标志,不包括tracking_content和fingerprinting_content。any_strict_tracking:一个元标志,结合了所有跟踪和指纹识别标志。any_social_tracking:一个元标志,结合了所有社交跟踪标志。
您可以在 disconnect.me 网站上找到有关跟踪器类型的更多信息。
content后缀表示跟踪并提供内容的跟踪器。阻止它们可以保护用户,但也可能导致网站损坏或元素无法显示。
示例
此代码观察目标 URL 的身份验证请求
const target = "https://intranet.company.com/";
function observe(requestDetails) {
console.log(`observing: ${requestDetails.requestId}`);
}
browser.webRequest.onAuthRequired.addListener(observe, { urls: [target] });
此代码取消目标 URL 的身份验证请求
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",
]);
此代码同步提供凭据。它跟踪未完成的请求,以确保不会重复提交错误的凭据
const target = "https://intranet.company.com/";
const myCredentials = {
username: "me@company.com",
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] });
此代码异步提供凭据,从存储中获取它们。它还跟踪未完成的请求,以确保不会重复提交错误的凭据
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 };
}
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] });
扩展程序示例
浏览器兼容性
加载中…
注意:此 API 基于 Chromium 的 chrome.webRequest API。此文档来源于 Chromium 代码中的 web_request.json。