【问题标题】:Using rejectUnauthorized with node-fetch in node.js在 node.js 中将 rejectUnauthorized 与 node-fetch 一起使用
【发布时间】:2020-05-20 12:03:57
【问题描述】:

我目前使用 request 在 node.js 中发出 http 请求。我在某个时候遇到了一个问题,我收到了指示 UNABLE_TO_GET_ISSUER_CERT_LOCALLY 的错误。为了解决这个问题,它设置了rejectUnauthorized。我的请求工作代码如下所示:

    var url = 'someurl';
    var options = {
        url: url,
        port: 443,
        // proxy: process.env.HTTPS_PROXY, -- no need to do this as request honors env vars
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko',
            'Accept-Language': 'en-us',
            'Content-Language': 'en-us'
        },
        timeout: 0,
        encoding: null,
        rejectUnauthorized: false // added this to prevent the UNABLE_TO_GET_ISSUER_CERT_LOCALLY error
    };
    request(options, function (err, resp, body) {
        if (err) reject(err);
        else resolve(body.toString());
    });

我想我会尝试使用 async/await 切换到 fetch api,现在我正在尝试使用 node-fetch 来做同样的事情。但是,当我做同样的事情时,我又回到了 UNABLE_TO_GET_ISSUER_CERT_LOCALLY 错误。我读到我需要使用代理并尝试使用代理模块,但我仍然没有任何运气。

根据https://github.com/TooTallNate/node-https-proxy-agent/issues/11 的帖子,我认为以下方法可行:

    var options = {
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko',
            'Accept-Language': 'en-us',
            'Content-Language': 'en-us'
        },
        timeout: 0,
        encoding: null
    };
    var proxyOptions = nodeurl.parse(process.env.HTTPS_PROXY);
    proxyOptions.rejectUnauthorized = false;
    options.agent = new ProxyAgent(proxyOptions);
    const resp = await fetch('someurl', options);
    return await resp.text();

但我仍然遇到同样的错误。到目前为止,我能够使用 node-fetch 解决这个问题的唯一方法是在我的环境中设置 NODE_TLS_REJECT_UNAUTHORIZED=0 ,而我真的不想这样做。有人可以帮我看看如何让rejectUnauthorized 与node-fetch 一起工作(大概使用代理,但老实说,我并不关心它被指定为请求的一部分多长时间)。

【问题讨论】:

  • 试试隧道模块吧!较新版本的node-https-proxy-agent有问题!您可以使用旧版本 3.x 及以下版本!它会起作用的!否则只需使用隧道模型!这是我的经验以及我如何让它发挥作用!
  • 我也更新了问题!它有一个很好的例子,这个包可能很有趣(我在节点隧道上制作的一个包装器)npmjs.com/package/proxy-http-agent

标签: javascript node.js fetch node-fetch


【解决方案1】:

这就是我在 Node.js 应用程序中使用 rejectUnauthorizedFetch API 的方法。

请记住,使用rejectUnauthorized 是危险的,因为它会为您带来潜在的安全风险,因为它会绕过有问题的证书。

const fetch = require("node-fetch");
const https = require('https');

const httpsAgent = new https.Agent({
  rejectUnauthorized: false,
});

async function getData() {
  const resp = await fetch(
    "https://myexampleapi.com/endpoint",
    {
      agent: httpsAgent,
    },
  )
  const data = await resp.json()
  return data
}

【讨论】:

    【解决方案2】:

    使用代理

    您应该知道 node-https-proxy-agent 最新版本有问题并且不适用于 Fetch您可以使用旧版本 3.x 及以下版本!它会起作用的!否则更好的是你可以使用 node-tunnel 模块https://www.npmjs.com/package/tunnel!您也可以使用基于 node-tunnel https://www.npmjs.com/package/proxy-http-agent 的包装模块 proxy-http-agent!为代理提供自动检测协议!一种方法适合所有人!还有更多的选择和亲和力!而且它们都支持http和https!

    您可以在此模块和 repo 中查看用法并查看代理构建和设置的一个很好的示例(检查测试): https://www.npmjs.com/package/net-proxy https://github.com/Glitnirian/node-net-proxy#readme

    例如:

    import { ProxyServer } from 'net-proxy';
    import { getProxyHttpAgent } from 'proxy-http-agent';
    
    // ...
    
    // __________ setting the proxy
    
    const proxy = new ProxyServer({
        port: proxyPort
    });
     
    proxy.server.on('data', (data: any) => { // accessing the server instance
        console.log(data);
    });
     
    await proxy.awaitStartedListening(); // await server to start
     
    // After server started
     
    // ______________ making the call through the proxy to a server through http:
    
    let proxyUrl = `http://localhost:${proxyPort}`; // Protocol from the proxy is automatically detected
    
    let agent = getProxyHttpAgent({
        proxy: proxyUrl,
        endServerProtocol: 'http:' // the end server protocol (http://localhost:${localApiServerPort} for example)
    });
     
    const response = await fetch(`http://localhost:${localApiServerPort}`, {
        method: 'GET',
        agent 
    });
    
    // ___________________ making a call through the proxy to a server through https:
    
    agent = getProxyHttpAgent({
        proxy: proxyUrl, // proxy as url string! We can use an object (as tunnel module require too)
        rejectUnauthorized: false // <==== here it go
    });
    
    const response2 = await fetch(`https://localhost:${localApiHttpsServerPort}`, {
        method: 'GET',
        agent
    });
    

    您可以在此处的文档中查看更多示例和详细信息:

    https://www.npmjs.com/package/proxy-http-agent

    你也可以直接使用node-tunnel!但是包只是一个简单的包装器!这使它更简单!

    添加rejectUnauthorized

    对于不太了解的人!

    根据这个帖子

    https://github.com/node-fetch/node-fetch/issues/15

    我们使用https.Agent来传递rejectUnauthorized参数!

    const agent = new https.Agent({
      key: fs.readFileSync(`${CERT_PATH}.key`),
      cert: fs.readFileSync(`${CERT_PATH}.crt`),
      rejectUnauthorized: false
    })
    

    一个完整的例子

    import https from "https";
    const agent = new https.Agent({
      rejectUnauthorized: false
    });
    fetch(myUrl, { agent });
    

    对于获取,您也可以使用如下环境变量

    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    

    这样它将在全局范围内设置,而不是每次调用!如果您使用的是常量代理,这可能更合适!所有电话!就像坐在公司代理后面一样!

    为什么

    默认节点获取!和大多数http请求客户端!使用 https 时,所有人都使用安全性并确保有效的 ssl 证书! 要禁用此行为,我们需要以某种方式禁用该检查! 根据库的不同,它可能会有所不同!

    对于 fetch 就是这样完成的!

    使用 http.request! (底层)

    const https = require('https');
    
    const options = {
      hostname: 'encrypted.google.com',
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false /// <<<== here
    };
    
    const req = https.request(options, (res) => {
      console.log('statusCode:', res.statusCode);
      console.log('headers:', res.headers);
    
      res.on('data', (d) => {
        process.stdout.write(d);
      });
    });
    
    req.on('error', (e) => {
      console.error(e);
    });
    req.end();
    

    检查一下:

    https://nodejs.org/api/https.html#https_https_request_url_options_callback

    它也是tls.connect 选项的一部分

    你可以在这里查看

    https://nodejs.org/api/tls.html#tls_tls_connect_options_callback

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-11
      • 2019-03-14
      • 2017-11-25
      • 1970-01-01
      • 2017-12-02
      • 2017-10-17
      • 2017-09-29
      • 2018-05-15
      相关资源
      最近更新 更多