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
的返回值。
- 在 addListener 中,在
请参阅 示例。
如果您的扩展提供了错误的凭据,则会再次调用侦听器。因此,请注意避免通过重复提供错误的凭据进入无限循环。
权限
在 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 授权)。侦听器不能取消系统请求或对任何系统请求进行任何其他修改。
语法
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.BlockingResponse
或Promise
,具体取决于extraInfoSpec
中的设置。 filter
-
webRequest.RequestFilter
。限制发送到此侦听器的事件的过滤器。 extraInfoSpec
可选-
string
的array
。事件的其他选项。您可以传递以下任何值"blocking"
:使请求阻塞,以便您可以取消请求或提供身份验证凭据。返回一个BlockingResponse
对象,并设置其cancel
或authCredentials
属性。- 在 Chrome 中,事件侦听器必须同步响应。
- 在 Firefox 中,事件侦听器可以同步响应或返回一个解析为
BlockingResponse
对象的 promise 以异步响应。
"asyncBlocking"
:异步处理请求。事件侦听器的返回值将被忽略。要解决事件,请将asyncCallback
参数传递给BlockingResponse
对象。- Chrome 120 和 Firefox 128 及更高版本支持。
- Safari 不支持。
其他对象
details
challenger
-
object
。请求身份验证的服务器。这是一个具有以下属性的对象 -
string
。如果请求来自在上下文身份中打开的标签页,则为上下文身份的 cookie 存储 ID。有关更多信息,请参阅 使用上下文身份。 frameId
-
整数
。如果请求发生在主框架中,则为0
;正值是发生请求的子框架的 ID。如果(子)框架的文档被加载(type
为main_frame
或sub_frame
),则frameId
指示此框架的 ID,而不是外部框架的 ID。框架 ID 在一个选项卡内是唯一的。 incognito
-
布尔值
。请求是否来自隐私浏览窗口。 isProxy
-
布尔值
。Proxy-Authenticate
为true
,WWW-Authenticate
为false
。注意:
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
-
字符串
数组。请求或其窗口层次结构的第三方的分类标志。
分类标志包括
fingerprinting
和fingerprinting_content
:指示请求参与指纹识别(“发现可用于指纹识别的来源”)。fingerprinting
指示该域名属于指纹识别和跟踪类别。此类域名的示例包括想要将个人资料与访问用户关联的广告客户。fingerprinting_content
指示该域名属于指纹识别类别,但不属于跟踪类别。此类域名的示例包括使用指纹识别技术识别访问用户以进行反欺诈的支付提供商。
cryptomining
和cryptomining_content
:与指纹识别类别类似,但用于加密挖矿资源。tracking
、tracking_ad
、tracking_analytics
、tracking_social
和tracking_content
:指示请求参与跟踪。tracking
是任何通用的跟踪请求。ad
、analytics
、social
和content
后缀标识跟踪器的类型。any_basic_tracking
:一个元标志,结合了跟踪和指纹识别标志,不包括tracking_content
和fingerprinting_content
。any_strict_tracking
:一个元标志,结合了所有跟踪和指纹识别标志。any_social_tracking
:一个元标志,结合了所有社交跟踪标志。
示例
此代码观察目标 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: "[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] });
此代码异步提供凭据,从存储中获取它们。它还跟踪未完成的请求,以确保不会重复尝试提交错误的凭据
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
。