首页 > 解决方案 > 从 Node.js 调用带有自签名证书的 URL:DEPTH_ZERO_SELF_SIGNED_CERT

问题描述

我有一个使用 Flask 在 localhost 上运行的 Python 应用程序。我为 localhost 创建了一个自签名证书(也为此创建了一个 CA),并将 localhost.crt 证书和 localhost.key 作为私钥加载到 Flask 应用程序中:

app = Flask(__name__)
context = ssl.SSLContext()
context.load_cert_chain(certfile='localhost.crt', keyfile='localhost.key', password='my_password')
app.run(host='127.0.0.1', port=5000, ssl_context=context)

在此之后,我将 CA 的 pem 文件导入 Windows 的信任库。如果我在 Chrome 中调用服务器一切都很好。

但是,我在使用 axios 的同一台 PC 上有一个 Node.js 应用程序。如果我从 Node.js 调用上面的 Python 应用程序,我会得到:

Error: self signed certificate
    at TLSSocket.onConnectSecure (_tls_wrap.js:1514:34)
    at TLSSocket.emit (events.js:375:28)
    at TLSSocket._finishInit (_tls_wrap.js:936:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:708:12) {
  code: 'DEPTH_ZERO_SELF_SIGNED_CERT',

我花了一些时间寻找解决方案,一些帖子提到了这一点,所以我将 CA pem 文件加载到 https 代理的 ca 字段中:

var https = require('https');
https.globalAgent.options.ca = fs.readFileSync(path.join(__dirname, './myCA.pem'));

但这不起作用。

我尝试在 axios 请求中添加一个新代理:

var agent = new https.Agent({
  ca: fs.readFileSync(path.join(__dirname, './myCA.pem'))
});
var config = {
  method: 'get',
  url: 'https://localhost:5000/test',
  headers: { },
  httpsAgent: agent
};
axios(config).then(function (response) {
  console.log(JSON.stringify(response.data));
}).catch(function (error) {
  console.log(error);
});

但我得到相同的结果。有些帖子提到我需要在这里添加一个 CA 包,但我只有一个 CA 文件,如果需要,我如何创建一个包?

在生成过程中,我创建了这些文件:

localhost.crt
localhost.csr
localhost.ext
localhost.key
myCA.key
myCA.pem
myCA.srl

注意:使用 rejectUnauthorized (和类似的)不是一个选项。

标签: node.jssslhttpsopensslcertificate

解决方案


经过大量阅读和尝试后解决。创建 myCA.pem 证书和 localhost.crt 证书时,我使用了相同的通用名称。如我的问题中所述,在使用不同的 httpsAgent 并在 axios 中指定新的 httpsAgent 后,它一切正常。


推荐阅读