node.js - Puppeteer:仅为主页域添加基本身份验证 header ,不适用于第 3 方请求

标签 node.js puppeteer basic-authentication google-chrome-headless

我正在尝试让 puppeteer 操纵者发送 Authorization header ,而不会收到质询,仅针对第一方/第二方请求 - 即不发送给第三方,并且没有意想不到的后果。主要目标是在需要的地方进行身份验证,并避免泄漏 Authorization + Referer

的 killer 级组合

使用 page.authenticate() 是行不通的,因为它需要一个挑战。使用 page.setExtraHTTPHeaders() 设置 header ,然后将其发送给第三方。使用 page.setRequestInterception() 允许我引入一些条件逻辑,并且确实解决了主要目标,但它似乎增加了一堆复杂性和意想不到的后果(例如围绕缓存)。

我的具体用例是围绕 webfonts,fwiw。

以下是我如何使用 page.setExtraHTTPHeaders(在本例中为 httpbin)确认额外 header 已发送给第三方

为 httpbin.org/headers 提供带有 iframe 的简单页面:

var http = require('http')

http.createServer(function (request, response) {
    console.log(request.headers)
    response.writeHead(200)
    response.end('<iframe src="http://httpbin.org/headers" width="100%" height="100%"></iframe>\n')
}).listen(8000)

使用 puppeteer 获取该页面:

const puppeteer = require('puppeteer');
const url = 'http://localhost:8000';

(async () => {
  const browser = await puppeteer.launch()

  const page = await browser.newPage()

  await page.setExtraHTTPHeaders({ Authorization: 'Basic dXNlcjpwYXNz' })
  //await page.authenticate({ username: 'user', password: 'pass' })
  await page.goto(url)
  await page.screenshot({path: '/tmp/headers.png'})

  await browser.close()
})()

httpbin.org/headers 响应的内容(使用 tcpflow -c 在网络上捕获):

 {
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "en-GB", 
    "Authorization": "Basic dXNlcjpwYXNz",  <----- Authorization is forwarded
    "Host": "httpbin.org", 
    "Referer": "http://localhost:8000/", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/83.0.4103.0 Safari/537.36", 
    "X-Amzn-Trace-Id": "Root=1-5ecdb903-0c61b77370a47d894aa8aa7c"
  }
}

最佳答案

您可以使用 request.isNavigationRequest() 方法过滤掉任何不针对主域的请求,以便在应用 auth header 等时进行限制。

在 GitHub puppeteer 项目上报告了类似的问题导致添加了这个方法,作者给出了这个例子 usage :

    // enable request interception
    await page.setRequestInterception(true);
    // add header for the navigation requests
    page.on('request', request => {
      // Do nothing in case of non-navigation requests.
      if (!request.isNavigationRequest()) {
        request.continue();
        return;
      }
      // Add a new header for navigation request.
      const headers = request.headers();
      headers['X-Just-Must-Be-Request-In-Main-Request'] = 1;
      request.continue({ headers });
    });
    // navigate to the website
    await page.goto('https://example.com');

关于node.js - Puppeteer:仅为主页域添加基本身份验证 header ,不适用于第 3 方请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62034099/

相关文章:

javascript - Node Puppeteer,page.on( "request") 抛出 "Request is already handled!"

javascript - Puppeteer ,监听网络响应变化

node.js - 如何使用 Websocket 构建可扩展的实时聊天消息传递?

javascript - 在 Node.js 和 sails.js 中链接异步函数

url - page.click 不是函数

http - Apache 身份验证 : Redirect on failure, 可靠吗?

ruby-on-rails - 在 RSpec 测试中跳过 Rails http_basic_authenticate_with

android - RxAndroid Release Apk 不适用于 build 25.0.2

javascript - 从 js Map 解析文本

node.js - 使用适用于 Java 的 AWS 开发工具包调用 AWS Lambda 函数时如何检索 context.done() 消息?