在node.js中对节点获取使用rejectUnauthorized

pdtvr36n  于 2023-03-01  发布在  Node.js
关注(0)|答案(2)|浏览(594)

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

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_TLS_REJECT_UNAUTHORIZED=0,但我并不真的想这样做。有人能帮助我演示如何让rejectUnauthorized与节点获取一起工作吗(可能使用代理,但我真的不关心如何,只要它被指定为请求的一部分)。

knpiaxh1

knpiaxh11#

请️记住,使用rejectUnauthorized是危险的,因为它会使您面临潜在的安全风险,因为它会绕过有问题的证书。
这就是我如何在Node.js应用程序中使用rejectUnauthorizedFetch API来实现这一点的。

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

mrphzbgm2#

使用代理

您应该知道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的 Package 模块proxy-http-agent!即提供自动检测协议的代理!一种方法适用于所有!和更多的选项和亲和力!而且两者都支持http和https!
您可以在此模块和repo中查看用法和代理构建和设置的良好示例(检查测试):例如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
你也可以直接使用节点隧道!但是这个包只是一个简单的 Package 器!这使得它更简单!

添加拒绝未授权

为了一个不了解的人!
根据此线程
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请求客户端!所有使用的安全性和确保有效的ssl证书时使用https!要禁用此行为,我们需要禁用该检查以某种方式!取决于库,它可能是不同的!
对于取球来说就是这样!

使用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

相关问题