【问题标题】:Node.js HTTPS 400 Error - 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'Node.js HTTPS 400 错误 - 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
【发布时间】:2012-03-15 11:00:54
【问题描述】:

我正在编写一个 Node.js 应用程序,它必须从我们的一个内部 API 请求一些数据。棘手的部分是我从中请求数据的服务器有一定的限制:

  • 请求必须使用 HTTPS 协议(不是 HTTP)
  • 请求必须使用 LAN IP 地址,因为该域名在内部不起作用
  • 请求必须看起来像是从外部域名请求的,因为虚拟主机就是为此设置的。

为了做到这一点,我正在运行一些看起来像这样的代码:

var headers = {
    Host: externalHostname,
    Hostname: externalHostname,
};

var options = {
    host: InternalIP,
    path: path,
    method: 'GET',
    headers: headers
};

var req = https.request(options, function(res) {
    res.setEncoding('utf8');

    var data = "";

    res.on('data', function(chunk) {
        data += chunk;
    });

    res.on('end', function() {
        //Do something with that data
    });

    res.on('error', function(err) {
            console.log("Error during HTTP request");
            console.log(err);
    });
});

req.end();

很遗憾,我收到了 400(您的浏览器发送了此服务器无法理解的请求)错误作为响应。我反复检查了主机名、IP 地址和路径名是否正确(我可以在浏览器中测试它们,一切都很好)。

我输出了我的响应变量 (res),并收到了 UNABLE_TO_VERIFY_LEAF_SIGNATURE 的 authorizationError 值。我不确定那是什么,或者是否是我的问题,但这是我能找到的唯一有用的信息。

我把我的响应变量here的完整输出。

关于可能导致此问题的任何想法?

更新:我想通了!我试图通过传递 ?PHPSESSID=asdad GET 变量来向服务器进行身份验证,但他们已禁用该变量。我可以通过在 Cookie 标头中设置 PHPSESSID 来使其工作。

【问题讨论】:

  • 你在var https = require('https');上方的某处有这样的一行吗?
  • @MikeL。对。 https 是一个全局变量,我知道它正在工作,因为实际的 HTTPS 请求会触发 - 它只是响应 400 错误。
  • 您的选项中还缺少method:['get','post']...这是文档nodejs.org/docs/v0.4.0/api/https.html#https.request
  • @MikeL。刚刚添加 - 没有运气。
  • 我现在正在查看authorizationError: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' 错误...是您的 SSL 证书。自签?

标签: node.js ssl https


【解决方案1】:

设置这个process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

【讨论】:

  • 谢谢!这解决了我的 node.js 和僵尸问题,并且能够在提琴手中观察 HTTPs 流量(以及必须将僵尸浏览器选项设置为提琴手代理)
  • 这是个糟糕的主意。如果系统具有正确的 CA 根(AKA 锚)证书,则应该有一种方法可以将它们告知 Node,而不是关闭 strict-ssl
【解决方案2】:

我在从我的 nodejs 服务器的外部 api 调用中调试 UNABLE_TO_VERIFY_LEAF_SIGNATURE 错误时点击这里。

服务器证书验证过程中出现错误时会出现此错误。虽然不建议通过以下代码禁用安全性(也可作为另一个答案),但它有助于验证您是否正在寻找正确的错误。换句话说,如果放这个也不能修复它,那么代码还有其他问题。

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

在我的情况下,有一个愚蠢的错误 & 请求将发送到 localhost 本身。即使在完成上述操作后,请求也失败了,这帮助我发现了错误。

话虽如此,不建议将其用作解决方案。而是弄清楚如何通过设置 agent:falseca:[fs.readFileSync('root-cert.pem')] 选项来提供额外的证书。 https.request 文档提供了详细信息。在追逐我的错误时,我还发现了一些更有用的资源:

  1. ssl-tools.net 站点提供根证书和中间证书。例如:lives.api.net 使用的Baltimore CyberTrust Root
  2. ssl-root-cas module 声称提供流行浏览器使用的额外 CA 证书。我尚未验证该声明。
  3. openssl s_client -connect apis.live.net:443 -- 打印证书链。您需要将最后一个参数(url 和端口)替换为您要连接的内容。

【讨论】:

    【解决方案3】:

    从最新 node.js 中的 tls.js 源代码中检查一下(我认为您需要的还有更多)

    // 认证模式 // // TLS/SSL 支持多个级别的身份验证。 // 在“man SSL_set_verify”中了解更多信息。 // // 1. 服务器向客户端发送证书但不请求 // 来自客户端的证书。这对于大多数 HTTPS 服务器很常见。浏览器 // 可以验证服务器的身份,但是服务器不知道是谁 // 客户端是。验证客户端通常通过 HTTP 使用 // 登录框和 cookie 等。 // // 2. 服务器向客户端发送证书并请求客户端 // 也给它发送一个证书。客户端知道服务器是谁,服务器是谁 // 请求客户端也标识自己。有几种 // 结果: // // A) verifyError 返回 null 表示客户端的证书已签名 // 由服务器的 CA 之一。服务器现在知道客户端身份 // 并且客户端被授权。 // // B) 出于某种原因,客户端的证书不可接受 - // verifyError 返回一个指示问题的字符串。服务器可以 // (i) 拒绝客户端或 (ii) 允许客户端作为连接 // 未经授权的连接。 // // 模式由两个布尔变量控制。 // // 请求证书 // 如果为 true,则服务器从客户端连接请求证书。为了 // 常见的 HTTPS 情况,用户会希望 this 为 false,这就是 // 它默认为。 // // 拒绝未授权 // 如果证书因任何原因无效的真实客户将不会 // 允许建立连接。如果为假,它们将被简单地标记为 // 未经授权但安全的通信将继续。默认情况下这是 // 错误的。 //

    在您的选项中将 rejectUnauthorized 设置为 false 并交叉手指...如果输出发生变化,请告诉我。

    【讨论】:

    • devel.dyne.org/jmx/tree/jsapi/node/… 这是源代码,查看第 755 行
    • 我想你的情况可能有点倒退。这(我相信)是如果我正在创建一个 SSL 服务器 - 该文档中的措辞似乎表明在服务器上设置了 requestCert 和 rejectUnauthorized 。但是,我正在尝试从不同的(apache)服务器发出 HTTPS 请求。
    • 如果是这样,那么UNABLE_TO_VERIFY_LEAF_SIGNATURE是你的服务器返回给你的东西,那个错误与node.js无关
    • @MikeL。这是牛。我现在对外部 API 有一个简单的请求函数,我得到了UNABLE_TO_VERIFY_LEAF_SIGNATURE,并且在 Postman 中应用了相同的标头并且它运行良好。这是为什么?你怎么能告诉我它与节点无关?
    【解决方案4】:

    设置这个process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; 修复了 superagent 的 UNABLE_TO_VERIFY_LEAF_SIGNATURE 问题。

    【讨论】:

      【解决方案5】:

      在命令行中试试这个:

      npm config set strict-ssl false
      

      它在 mac 上对我有用。

      【讨论】:

      • 这是个糟糕的主意。如果系统具有正确的 CA 根(AKA 锚)证书,则应该有一种方法可以将它们告知 Node,而不是关闭 strict-ssl
      猜你喜欢
      • 2013-08-29
      • 2018-10-28
      • 2019-01-24
      • 2014-01-11
      • 2014-09-20
      • 2014-01-24
      • 2015-01-25
      • 2018-08-27
      • 2012-07-04
      相关资源
      最近更新 更多