Node.js 请求 CERT_HAS_EXPIRED

IT技术 javascript node.js express request
2021-03-13 00:24:22

我正在使用 Mikeal 的请求 ( https://github.com/mikeal/request ) 向服务器发出 https 请求。但是,我不断收到 CERT_HAS_EXPIRED 的授权错误。

request({
        url: 'https://www.domain.com/api/endpoint',
        strictSSL: false
    }, function(error, response, body) {
        if(!error && response.statusCode == 200) {
            res.json(JSON.parse(body));
        } else {
           res.json(response.statusCode, {'error': 'error'})
        }
});

我试过将strictSSL 设置为true 和false,两者都输出相同的CERT_HAS_EXPIRED 错误。是什么导致了这个问题,有什么办法可以在 nodejs 中修复它?

6个回答

解决此问题的最佳方法:

更新证书。这可以使用Greenlock免费完成,它通过 Let's Encrypt™ v2 颁发证书

不安全的方式来解决这个问题:

'use strict';

var request = require('request');
var agentOptions;
var agent;

agentOptions = {
  host: 'www.example.com'
, port: '443'
, path: '/'
, rejectUnauthorized: false
};

agent = new https.Agent(agentOptions);

request({
  url: "https://www.example.com/api/endpoint"
, method: 'GET'
, agent: agent
}, function (err, resp, body) {
  // ...
});

通过agentrejectUnauthorized您一起使用,至少可以将安全漏洞限制在处理该站点的请求上,而不是使您的整个节点进程完全、完全不安全。

其他选项

如果您使用的是自签名证书,则应添加此选项:

agentOptions.ca = [ selfSignedRootCaPemCrtBuffer ];

对于受信任的对等连接,您还可以添加以下 2 个选项:

agentOptions.key = clientPemKeyBuffer;
agentOptions.cert = clientPemCrtSignedBySelfSignedRootCaBuffer;

馊主意

不幸的是,process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';它甚至被记录在案。它应该只用于调试,并且永远不应该将它变成可以在野外运行的代码。几乎每个运行在上面的库https都有一种传递代理选项的方法。那些不应该被修复的。

如果您创建了自签名证书,那么您将使用同一个自签发根证书的 pem 版本作为缓冲区。
2021-04-24 00:24:22
当证书不是自签名或过期时有什么想法,但节点抱怨它已过期?
2021-05-09 00:24:22
[selfSignedRootCaPemCrtBuffer] 是什么意思?如果我知道它在哪里,如何提供缓冲区?
2021-05-13 00:24:22

在文件顶部添加:

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

危险这会在整个 node.js 环境中禁用 HTTPS / SSL / TLS 检查。请参阅下面使用 https 代理的解决方案。

@CoolAJ86 在某些情况下可以使用它。现在我正在等待更新开发 API 服务器上的过期 SSL 证书。它阻碍了我的工作能力,在此期间忽略 SSL 问题是一个非常好的情况。
2021-04-20 00:24:22
请取消将此标记为解决方案。有危险。
2021-04-25 00:24:22
@CoolAJ86 对于我的用例,您缺乏所有上下文,它不适用。抱歉,您的原教旨主义无济于事。
2021-05-11 00:24:22
@CoolAJ86 如果我有一个本地应用程序,它只与本地环境中的登台服务器建立 HTTPS 连接,那么绝对没有功能差异。因此,这是一个可接受的解决方案。
2021-05-15 00:24:22
每次你使用这个解散解决方案时,NSA 特工都会长出翅膀。
2021-05-17 00:24:22

如果今天有人在使用旧版本的 nodejs 时遇到这个问题,这可能是由于Lets's encrypt 9 月 30 日。2021 ROOT CA 到期已在此答案中提及

证书在节点源代码中硬编码,新的 ISRG Root X1 证书仅在此提交中添加

可以更新他们的节点版本,使用node --use-openssl-ca标志(假设 openssl 证书是最新的),使用其他答案中提到的 http 代理解决方案(我没有测试它),或者设置process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0为一种快速而肮脏的解决方法。

我们的生产应用程序在 Heroku(Heroku-20 堆栈)上运行并使用 Node 8.9.4。我们还使用 Angular 5.2.11 和 Angular Universal 进行服务器端渲染。从 2021 年 10 月 1 日开始,我们的 Angular Universal https 请求突然停止工作,我们的页面没有呈现服务器端。只需在我们的 package.json“start”脚本中添加“node --use-openssl-ca”标志就解决了这个问题: "start": "set NODE_ENV=production&& node --use-openssl-ca server.js" 谢谢@Max Akn!
2021-04-28 00:24:22
Node.js 的更新(在我的例子中是最新的稳定版本 v16.10.0)成功了!不过,我不确定您是否选择了正确的提交 @max-akn,因为我之前的版本是 v8.17.0,而您共享的提交似乎从 v8.0.0 开始就包含在内。
2021-05-13 00:24:22

这里有一个更简洁的方式来实现 CoolAJ86 提出的“不太安全”的方法

request({
  url: url,
  agentOptions: {
    rejectUnauthorized: false
  }
}, function (err, resp, body) {
  // ...
});
如果您request从中导入https那么您甚至不需要agentOptions:rejectUnauthorized可以是直接传递给 的对象上的属性request
2021-05-15 00:24:22

我认为strictSSL: false应该(应该工作,即使在 2013 年)工作。简而言之,是三种可能的方式:

  1. (很明显)让你的 CA 更新证书,然后把它放到你的服务器上!
  2. 更改request对象的默认设置

    const myRequest = require('request').defaults({strictSSL: false})

    许多node-request内部使用的module也允许request注入 -object,因此您可以让它们使用修改后的实例。
  3. (不推荐)覆盖所有证书检查所有通过设置环境变量HTTP(S)代理连接NODE_TLS_REJECT_UNAUTHORIZED=0的Node.js的过程。
3. 刚刚通过具有 SSL 拦截的 MITM 代理将我从猴子补丁 kibana 5 中拯救出来以进行插件安装。
2021-05-02 00:24:22