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 的返回值

請參閱示例

如果您的擴充套件提供錯誤的憑據,那麼監聽器將再次被呼叫。因此,請注意避免透過重複提供錯誤的憑據而進入無限迴圈。

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 為代理授權提供憑據(但不能用於正常的網路授權)。監聽器不能取消系統請求或對任何系統請求進行任何其他修改。

語法

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 語法

引數

監聽器

此事件發生時呼叫的函式。該函式會傳遞以下引數:

details

object。有關請求的詳細資訊。有關更多資訊,請參閱 details 部分。

asyncCallback 可選

一個最多呼叫一次的函式,用於非同步修改請求物件。此引數僅在事件監聽器使用 extraInfoSpec 陣列中的 "asyncBlocking" 註冊時才存在。如果未提供 extraInfoSpec 或包含 "blocking",則 asyncCallback 未定義。

返回:webRequest.BlockingResponsePromise,具體取決於 extraInfoSpec 中的設定。

filter

webRequest.RequestFilter。一個限制傳送到此監聽器的事件的過濾器。

extraInfoSpec 可選

array 型別的 string。事件的額外選項。您可以傳遞以下任何值:

  • "blocking":使請求阻塞,以便您可以取消請求或提供身份驗證憑據。返回一個 BlockingResponse 物件,並設定其 cancelauthCredentials 屬性。

    • 在 Chrome 中,事件監聽器必須同步響應。
    • 在 Firefox 中,事件監聽器可以同步響應或返回一個解析為 BlockingResponse 物件的 Promise 以非同步響應。
  • "asyncBlocking":非同步處理請求。事件監聽器的返回值將被忽略。要解決事件,請將 asyncCallback 引數傳遞一個 BlockingResponse 物件。

    • Chrome 120 和 Firefox 128 開始支援。
    • Safari 不支援。

額外物件

details

challenger

object。請求身份驗證的伺服器。這是一個包含以下屬性的物件:

主機

string。伺服器的主機名

port

integer。伺服器的埠號。

cookieStoreId

string。如果請求來自上下文身份中開啟的標籤頁,則為上下文身份的 cookie 儲存 ID。有關更多資訊,請參閱使用上下文身份

frameId

integer。如果請求發生在主框架中,則為 0;正值表示請求發生的子框架的 ID。如果載入了(子)框架的文件(typemain_framesub_frame),frameId 表示此框架的 ID,而不是外部框架的 ID。框架 ID 在一個標籤頁內是唯一的。

incognito

boolean。請求是否來自隱私瀏覽視窗。

isProxy

boolean。對於 Proxy-Authenticatetrue,對於 WWW-Authenticatefalse

注意: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。請求或其視窗層次結構的第三方分類標誌。

分類標誌包括:

  • fingerprintingfingerprinting_content:表示請求涉及指紋識別(“發現指紋識別的來源”)。
    • fingerprinting 表示該域屬於指紋識別和跟蹤類別。此類域的示例包括希望將配置檔案與訪問使用者關聯的廣告商。
    • fingerprinting_content 表示該域屬於指紋識別類別但不屬於跟蹤類別。此類域的示例包括使用指紋識別技術識別訪問使用者以進行反欺詐目的的支付提供商。
  • cryptominingcryptomining_content:類似於指紋識別類別,但用於加密挖礦資源。
  • trackingtracking_adtracking_analyticstracking_socialtracking_content:表示請求涉及跟蹤。tracking 是任何通用跟蹤請求。adanalyticssocialcontent 字尾標識跟蹤器的型別。
  • emailtrackingemailtracking_content:表示請求涉及跟蹤電子郵件。
  • any_basic_tracking:一個元標誌,結合了跟蹤和指紋識別標誌,不包括 tracking_contentfingerprinting_content
  • any_strict_tracking:一個元標誌,結合了所有跟蹤和指紋識別標誌。
  • any_social_tracking:一個元標誌,結合了所有社交跟蹤標誌。

您可以在 disconnect.me 網站上找到有關跟蹤器型別的更多資訊。content 字尾表示跟蹤並提供內容的跟蹤器。阻止它們可以保護使用者,但也可能導致網站損壞或元素無法顯示。

示例

此程式碼觀察目標 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: "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] });

此程式碼非同步提供憑據,從儲存中獲取它們。它還跟蹤未完成的請求,以確保不會重複提交錯誤的憑據

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 };
  }
  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