在 node.js 中使用 rejectUnauthorized 和 node-fetch

Chr*_*s H 8 javascript fetch node.js node-fetch

我目前使用 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());
    });

Run Code Online (Sandbox Code Playgroud)

我想我会尝试使用 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();
Run Code Online (Sandbox Code Playgroud)

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

Cod*_*ker 9

\xe2\x9a\xa0\xef\xb8\x8f 请记住,使用rejectUnauthorized是危险的,因为它会规避有问题的证书,从而使您面临潜在的安全风险。

\n

这就是我使用rejectUnauthorizedFetch API让它工作的方法在 Node.js 应用程序中

\n
const fetch = require("node-fetch");\nconst https = require(\'https\');\n\nconst httpsAgent = new https.Agent({\n  rejectUnauthorized: false,\n});\n\nasync function getData() {\n  const resp = await fetch(\n    "https://myexampleapi.com/endpoint",\n    {\n      agent: httpsAgent,\n    },\n  )\n  const data = await resp.json()\n  return data\n}\n
Run Code Online (Sandbox Code Playgroud)\n


Moh*_*lal 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 !

您可以在此模块和存储库中查看用法并查看代理构建和设置的好示例(检查测试): https://www.npmjs.com/package/net-proxy https://github.com/Glitnirian /节点网络代理#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
});
Run Code Online (Sandbox Code Playgroud)

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

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

你也可以直接使用节点隧道!但包装只是一个简单的包装!这让它变得更简单!

添加拒绝未经授权

对于不太了解的人来说!

根据这个线程

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

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

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
});
Run Code Online (Sandbox Code Playgroud)

一个完整的例子

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

对于 fetch,您也可以使用环境变量,如下所示

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

这样它就会被全局设置,而不是每次调用!如果您使用常量代理,这可能更合适!对于所有来电!就像坐在公司代理后面一样!

为什么

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

对于 fetch 来说就是这样完成的!

通过http.request!(潜在的)

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
Run Code Online (Sandbox Code Playgroud)

检查这个:

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