Node.js HTTPS 400错误 – 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'

我正在写一个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地址和path名都是正确的(我可以在我的浏览器中testing它们,一切都很好)。

我做了我的响应variables(res)的输出,并且正在接收UNABLE_TO_VERIFY_LEAF_SIGNATURE的authorizationError值。 我不确定那是什么,或者是我的问题,但这是我能find的唯一有用的信息。

我在这里把我的响应variables的完整输出。

任何想法可能会导致这一点?

更新:我明白了! 我试图通过传递一个?PHPSESSID=asdad GETvariables来validation服务器,但他们已经禁用。 我可以通过在Cookie标头中设置PHPSESSID来使其工作。

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

我在这里打了debuggingUNABLE_TO_VERIFY_LEAF_SIGNATURE错误,在我的nodejs服务器的外部API调用。

服务器证书validation过程中发生错误时,会出现此错误。 虽然不build议通过以下代码禁用安全性(也可以作为其他答案),但它有助于validation您是否正在追查正确的错误。 换句话说,如果把这个也解决不了,代码还有其他问题。

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

在我的情况下,有愚蠢的错误和要求本地主机本身。 即使在上面提到,请求失败了,这帮助我发现了错误。

话虽如此,build议不要将此作为解决scheme。 相反,通过设置agent:falseca:[fs.readFileSync('root-cert.pem')]选项,您可以弄清楚如何提供额外的证书。 https.request文档提供了详细信息。 在追逐我的bug的同时,我也发现了更多有用的资源:

  1. ssl-tools.net站点提供根证书和中间证书。 例如:lives.api.net使用的Baltimore Cyber​​Trust Root
  2. ssl-root-cas模块声称提供了常用浏览器所使用的附加CA证书。 我没有证实这一说法。
  3. openssl s_client -connect apis.live.net:443 – 打印证书链。 您需要将最后一个参数(url和端口)replace为您要连接的参数。

从最新的node.js中的tls.js源代码中检查出来(还有更多这是我认为你需要的)

 //authentication模式
 //
 // TLS / SSL支持多种级别的身份validation。
 //在“man SSL_set_verify”中详细了解这个。
 //
 // 1.服务器向客户端发送证书,但不请求a
 //来自客户端的证书。 这在大多数HTTPS服务器中是很常见的。 浏览器
 //可以validation服务器的身份,但服务器不知道是谁
 //客户是 authentication客户端通常通过HTTP进行
 //login框和cookies和东西。
 //
 // 2.服务器向客户端发送证书并请求客户端
 //也发送一个证书。 客户端知道服务器和服务器是谁
 //请求客户也标识自己。 有几个
 //结果:
 //
 // A)verifyError返回null,表示客户端的证书已经签名
 //通过服务器的一个CA。 服务器现在知道客户端的身份
 //并且客户端被授权。
 //
 // B)由于某种原因,客户的证书是不可接受的 - 
 // verifyError返回一个表示问题的string。 服务器可以
 //(i)拒绝客户端或(ii)允许客户端连接
 //未经授权的连接
 //
 //模式由两个布尔variables控制。
 //
 // requestCert
 //如果为true,则服务器从客户端连接请求证书。 对于
 //常见的HTTPS情况下,用户会希望这是假的,这是什么
 //默认为。
 //
 // rejectUnauthorized
 //如果由于任何原因证书无效的真正的客户端将不会
 //被允许build立连接。 如果错误,他们将被简单地标记为
 //未经授权但安全的通信将继续。 这是默认的
 //假的
 //

在你的选项中设置rejectUnauthorized为false并且交叉手指…让我知道输出是否改变。

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

在命令行中试试这个:

 npm config set strict-ssl false 

它在mac上为我工作。