简体   繁体   English

Node.js 请求 CERT_HAS_EXPIRED

[英]Node.js request CERT_HAS_EXPIRED

I'm using Mikeal's request ( https://github.com/mikeal/request ) to make an https request to a server.我正在使用 Mikeal 的请求 ( https://github.com/mikeal/request ) 向服务器发出 https 请求。 However, I keep getting an authorization error of CERT_HAS_EXPIRED.但是,我不断收到 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'})
        }
});

I've tried setting strictSSL to true and false, both output same error of CERT_HAS_EXPIRED.我已经尝试将 strictSSL 设置为 true 和 false,两者都是 output 相同的 CERT_HAS_EXPIRED 错误。 What is causing this issue and is there any way to fix it in nodejs?是什么导致了这个问题,有没有办法在 nodejs 中修复它?

The best way to fix this:解决此问题的最佳方法:

Renew the certificate.更新证书。 This can be done for free using Greenlock which issues certificates via Let's Encrypt™ v2这可以使用Greenlock免费完成,它通过 Let's Encrypt™ v2 颁发证书

A less insecure way to fix this:一个不太不安全的方式来解决这个问题:

'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) {
  // ...
});

By using an agent with rejectUnauthorized you at least limit the security vulnerability to the requests that deal with that one site instead of making your entire node process completely, utterly insecure.通过使用带有rejectUnauthorizedagent ,您至少可以将安全漏洞限制在处理该站点的请求上,而不是让您的整个节点进程完全、完全不安全。

Other Options其他选项

If you were using a self-signed cert you would add this option:如果您使用的是自签名证书,则应添加此选项:

agentOptions.ca = [ selfSignedRootCaPemCrtBuffer ];

For trusted-peer connections you would also add these 2 options:对于受信任的对等连接,您还可以添加以下 2 个选项:

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

Bad Idea坏主意

It's unfortunate that process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';不幸的是process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; is even documented.甚至被记录在案。 It should only be used for debugging and should never make it into in sort of code that runs in the wild.它应该只用于调试,并且永远不应该将其放入在野外运行的代码中。 Almost every library that runs atop https has a way of passing agent options through.几乎每个在https上运行的库都有一种传递代理选项的方法。 Those that don't should be fixed.那些不应该被修复的。

Add this at the top of your file:在文件顶部添加:

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

DANGEROUS This disables HTTPS / SSL / TLS checking across your entire node.js environment.危险这会在整个 node.js 环境中禁用 HTTPS / SSL / TLS 检查。 Please see the solution using an https agent below.请参阅下面使用 https 代理的解决方案。

If someone is having this issue today while using an old version of nodejs, this might be due to Lets's encrypt 30th sept.如果今天有人在使用旧版本的 nodejs 时遇到此问题,这可能是由于Lets's encrypt 30th sept. 2021 ROOT CA expiry already mentionned in this answer .此答案中已提到2021 ROOT CA 到期

certificates are hardcoded in node source code and the new ISRG Root X1 certificate was only added in this commit .证书硬编码在节点源代码中,新的 ISRG Root X1 证书仅添加在此提交中。

One can either update their node version, use node --use-openssl-ca flag (assuming openssl certificates are up to date), use the http agent solution mentionned in other answers (I didn't test it), or set process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0 as a quick and dirty workaround.可以更新他们的节点版本,使用node --use-openssl-ca标志(假设 openssl 证书是最新的),使用其他答案中提到的 http 代理解决方案(我没有测试),或设置process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0作为一种快速而肮脏的解决方法。

Here is a more concise way to achieve the "less insecure" method proposed by CoolAJ86这里有一个更简洁的方式来实现 CoolAJ86 提出的“不那么不安全”的方法

request({
  url: url,
  agentOptions: {
    rejectUnauthorized: false
  }
}, function (err, resp, body) {
  // ...
});

I think the strictSSL: false should (should have worked, even in 2013) work.我认为strictSSL: false应该(即使在 2013 年也应该有效)有效。 So in short are three possible ways:简而言之,是三种可能的方式:

  1. (obvious) Get your CA to renew the certificate, and put it on your server! (很明显)让你的 CA 更新证书,然后把它放到你的服务器上!
  2. Change the default settings of your request object:更改request对象的默认设置:

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

    Many modules that use node-request internally also allow a request -object to be injected, so you can make them use your modified instance.许多内部使用node-request模块也允许注入request ,因此您可以让它们使用您修改过的实例。
  3. (not recommended) Override all certificate checks for all HTTP(S) agent connections by setting the environment variable NODE_TLS_REJECT_UNAUTHORIZED=0 for the Node.js process. (不推荐)通过设置环境变量重写所有证书检查所有HTTP(S)代理连接NODE_TLS_REJECT_UNAUTHORIZED=0为Node.js的过程。

尝试临时修改request.js,并在rejectUnauthorized = true 处硬编码,但最好将证书扩展为长期解决方案。

Updating Nodejs will force request's cache to be flushed.更新 Nodejs 将强制刷新请求的缓存。

This worked for me when nothing else did.当别无他法时,这对我有用。

I had this problem on production with Heroku and locally while debugging on my macbook pro this morning.今天早上在我的 macbook pro 上调试时,我在使用 Heroku 和本地进行生产时遇到了这个问题。

After an hour of debugging, this resolved on its own both locally and on production.经过一个小时的调试,这在本地和生产中自行解决。 I'm not sure what fixed it, so that's a bit annoying.我不确定是什么修复了它,所以这有点烦人。 It happened right when I thought I did something, but reverting my supposed fix didn't bring the problem back :(当我认为我做了某事时它发生了,但是恢复我假设的修复并没有把问题带回来:(

Interestingly enough, it appears my database service, MongoDb has been having server problems since this morning, so there's a good chance this was related to it.有趣的是,我的数据库服务 MongoDb 从今天早上开始就出现服务器问题,所以很有可能与它有关。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM