Node.js请求CERT_HAS_EXPIRED

www*_*ser 42 javascript request node.js express

我正在使用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'})
        }
});
Run Code Online (Sandbox Code Playgroud)

我已经尝试将strictSSL设置为true和false,两者都输出相同的CERT_HAS_EXPIRED错误.导致此问题的原因是什么方法可以在nodejs中修复它?

Coo*_*J86 96

解决此问题的最佳方法:

续订证书.这可以使用Greenlock免费完成,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) {
  // ...
});
Run Code Online (Sandbox Code Playgroud)

通过使用agentwith rejectUnauthorized至少可以将安全漏洞限制为处理该站点的请求,而不是使整个节点完全处理,完全不安全.

其他选择

如果您使用的是自签名证书,则可以添加以下选项:

agentOptions.ca = [ selfSignedRootCaPemCrtBuffer ];
Run Code Online (Sandbox Code Playgroud)

对于可信对等连接,您还可以添加以下两个选项:

agentOptions.key = clientPemKeyBuffer;
agentOptions.cert = clientPemCrtSignedBySelfSignedRootCaBuffer;
Run Code Online (Sandbox Code Playgroud)

馊主意

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

  • [selfSignedRootCaPemCrtBuffer] 是什么意思?如果我知道它在哪里,如何提供缓冲区? (2认同)
  • 如果您创建了一个自签名证书,那么您将使用同一个自发行根证书的 pem 版本作为缓冲区。 (2认同)
  • 当证书_未_自签名也未过期,但节点抱怨它已过期时,有什么想法吗? (2认同)

Max*_*Max 70

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

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

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

  • Node.js 的更新(在我的例子中是最新的稳定版本 v16.10.0)成功了!不过,我不确定您是否选择了正确的提交,@max-akn,因为我之前的版本是 v8.17.0,并且您共享的提交似乎是从 v8.0.0 开始包含的。 (3认同)

Dan*_*ohn 44

在文件顶部添加:

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

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

  • 每当你使用这个解决方案时,NSA代理就会获得它的支持. (26认同)
  • 请取消标记为解决方案.有危险. (18认同)
  • @ CoolAJ86有使用这种情况的有效情况.现在我正在等待更新开发API服务器上的过期SSL证书.它阻碍了我的工作能力,这是一个非常好的情况,只是忽略了过渡时期的SSL问题. (6认同)
  • @ CoolAJ86对于我的用例,你缺乏所有上下文,它不适用.对不起,但你的原教旨主义没有帮助. (5认同)
  • @ CoolAJ86如果我的本地应用程序只与本地环境中的登台服务器建立HTTPS连接,那么绝对没有功能差异.因此,这是可接受的解决方案. (4认同)

NTy*_*ler 18

这是一种更简洁的方法来实现CoolAJ86提出的"不太安全"的方法

request({
  url: url,
  agentOptions: {
    rejectUnauthorized: false
  }
}, function (err, resp, body) {
  // ...
});
Run Code Online (Sandbox Code Playgroud)

  • 如果您从“https”导入“request”,那么您甚至不需要“agentOptions”:“rejectUnauthorized”可以是直接传递给“request”的对象上的属性。 (2认同)

con*_*nny 8

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

  1. (显而易见)让您的CA续订证书,并将其放在您的服务器上!
  2. 更改request对象的默认设置:

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

    许多node-request内部使用的模块也允许request注入对象,因此您可以使用已修改的实例.
  3. (不推荐)覆盖所有对于证书检查所有通过设置环境变量HTTP(S)代理连接NODE_TLS_REJECT_UNAUTHORIZED=0的Node.js的过程.