nodejs - 证书链中的自签名证书错误

问题描述 投票:0回答:11

我面临客户端 https 请求的问题。

片段可以如下所示:

var fs = require('fs');
var https = require('https');

var options = {
    hostname: 'someHostName.com',
    port: 443,
    path: '/path',
    method: 'GET',
    key: fs.readFileSync('key.key'),
    cert: fs.readFileSync('certificate.crt')
}

var requestGet = https.request(options, function(res){
    console.log('resObj', res);
}

我得到的是错误:证书链中的自签名证书。

当我使用Postman时,我可以导入客户端证书和密钥并使用它,没有任何问题。有什么解决办法吗?我还希望了解邮递员如何处理证书和工作。

javascript node.js authentication ssl https
11个回答
236
投票

选项 1:禁用警告(对开发人员有用)

从你的问题来看,我猜测你正在开发中这样做,因为你正在使用自签名证书进行 SSL 通信。

如果是这种情况,请在运行节点的任何地方添加为环境变量

export NODE_TLS_REJECT_UNAUTHORIZED='0'
node app.js

或直接使用

运行节点
NODE_TLS_REJECT_UNAUTHORIZED='0' node app.js

这指示节点允许不受信任的证书(不受信任 = 未经证书颁发机构验证)

如果您不想设置环境变量或需要为多个应用程序执行此操作,npm 有一个

strict-ssl
配置,您可以将其设置为
false

npm config set strict-ssl=false

选项 2:加载 CA 证书,如邮递员(对于使用 TLS 进行测试很有用)

如果您已经拥有像海报 @kDoyle 提到的那样的 CA 证书,那么您可以在每个请求中进行配置(感谢 @nic ferrier)。

 let opts = {
    method: 'GET',
    hostname: "localhost",
    port: listener.address().port,
    path: '/',
    ca: fs.readFileSync("cacert.pem")
  };

  https.request(opts, (response) => { }).end();

选项 3:使用来自受信任来源的正确 SSL 证书(对生产有用)

letsencrypt.org 是免费的,易于设置,并且密钥可以自动轮换。 https://letsencrypt.org/docs/


52
投票

您可以在终端中使用

NODE_TLS_REJECT_UNAUTHORIZED=0
或在 JS 文件中插入以下行来解决此问题。

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;

请注意,这是一个 hack,不应该在生产中使用。

如果您使用的是 Windows,则在命令提示符中运行以下命令:

set NODE_TLS_REJECT_UNAUTHORIZED=0 

之后,

npm install <my-package>
就可以工作了。


19
投票

对于 Nodemailer:

添加

tls: {
  rejectUnauthorized: false
}

解决了我的问题。

整体代码看起来像这样:

nodemailer.createTransport({
    host: process.env.MAIL_SERVER,
    secure: false,
    port: 587,
    auth: {
      user: process.env.MAIL_USERNAME,
      pass: process.env.MAIL_PASSWORD
    },
    tls: {
      rejectUnauthorized: false
    }
  }

18
投票

您可以编写命令

npm config set strict-ssl false


14
投票

您只需在代码开头添加这一行:

process.env.NODE_TLS_REJECT_UNAUTHORIZED='0'

一切都解决了,但无论如何都不推荐,我正在研究

https://letsencrypt.org/

的解决方案

11
投票

关闭验证是一件非常危险的事情。更好地验证证书。

您可以使用选项对象的

ca
键将证书颁发机构证书拉入请求中,如下所示:

let opts = {
    method: 'GET',
    hostname: "localhost",
    port: listener.address().port,
    path: '/',
    ca: await fs.promises.readFile("cacert.pem")
  };

https.request(opts, (response) => { }).end();

我将整个演示放在一起,以便您可以了解如何构建 SSL 测试。

在这里


7
投票

做:

如果运行节点脚本用于独立目的,最好使用它,

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;

不要:

而不是更改所有默认请求流程。

npm config set strict-ssl=false

即,不要更改您的节点配置,否则它将通过将其设为默认配置来应用于您的所有请求。所以只在必要的时候使用它。


6
投票

节点应用程序需要将 CA 证书添加到现有 CA (Mozilla) 证书中。

我们使用服务启动节点,并添加环境变量 NODE_EXTRA_CA_CERTS

[Service]
Restart=always
User=<...>
Group=<...>
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
Environment=NODE_EXTRA_CA_CERTS=/<...>/.ssl/extra_certs.pem
WorkingDirectory=/<...>

ExecStart=/usr/bin/node -r dotenv/config /<.....>/server.js dotenv_config_path=/<....>/.env

这样我们就可以使用相同的应用程序来调用使用流行的 CA 或我们自己的自签名证书的服务,并且我们不必关闭 SSL 检查。

在 Linux 中,有一种简单的方法来获取证书,请使用这篇文章:使用带有 cURL 的自签名证书?

您使用以下方法创建证书:

$ echo quit | openssl s_client -showcerts -servername server -connect server:443 > cacert.pem

然后将该 .pem 文件复制为 extra_cert.pem。您只能拥有一个 pem 文件,但您可以将多个 pem 文件附加到一个文件中。

我希望这对某人有帮助,我花了一段时间才找到完成这项工作的不同部分。


3
投票

不管怎样,在花了一天半的时间试图追踪这个错误之后,结果发现这个错误是由我公司防火墙上的一项设置引起的,IT 部门必须禁用该设置。互联网上的任何地方都没有做任何事情来解决这个问题。


0
投票

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;尽管它没有起作用...

无法安装赛普拉斯:

SC:\Cypress> 导出 NODE_TLS_REJECT_UNAUTHORIZED='0' 节点 app.js 导出:术语“导出”不被识别为 cmdlet、函数、脚本的名称 文件或可运行的程序。检查名称的拼写,或者是否包含路径,
验证路径是否正确,然后重试。 在行:1 字符:1

  • 导出 NODE_TLS_REJECT_UNAUTHORIZED='0' 节点 app.js
  •   + CategoryInfo          : ObjectNotFound: (export:String) [], CommandNotFoundException   
      + FullyQualifiedErrorId : CommandNotFoundException
    
    

0
投票

你可以把你的js文件的这一行写在上面

=> process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

© www.soinside.com 2019 - 2024. All rights reserved.