node.js 如何配置 axios 使用 SSL 证书?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51363855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:52:05  来源:igfitidea点击:

How to configure axios to use SSL certificate?

node.jssslssl-certificateaxios

提问by Jemi Salo

I'm trying to make a request with axios to an api endpoint and I'm getting the following error: Error: unable to verify the first certificate

我正在尝试使用 axios 向 api 端点发出请求,但出现以下错误: Error: unable to verify the first certificate

It seems the https module, which axios uses, is unable to verify the SSL certificate used on the server.

axios 使用的 https 模块似乎无法验证服务器上使用的 SSL 证书。

When visiting the server with my browser, the certificate is valid and I can see/download it. I can also make requests to the api on my browser through https.

使用浏览器访问服务器时,证书有效,我可以查看/下载它。我还可以通过 https 向浏览器上的 api 发出请求。

I can work around it by turning off verification. This code works.

我可以通过关闭验证来解决它。此代码有效。

const result = await axios.post(
    `https://${url}/login`,
    body,
    {
      httpsAgent: new https.Agent({
        rejectUnauthorized: false
      })
    }
  )

Problem is, this doesn't verify the SSL certificate and therefore opens up security holes.

问题是,这不会验证 SSL 证书,因此会打开安全漏洞。

How can I configure axios to trust the certificate and correctly verify it?

如何配置 axios 以信任证书并正确验证它?

回答by srquinn

Old question but chiming in for those who land here. No expert. Please consult with your local security gurus and what not.

老问题,但对那些降落在这里的人来说。没有专家。请咨询您当地的安全专家,否则请咨询。

Axios is an http(s) client and http clients usually participate in TLS anonymously. In other words, the server accepts their connection without identifying who is trying to connect. This is different then say, Mutual TLS where both the server and client verify each other before completing the handshake.

Axios 是一个 http(s) 客户端,http 客户端通常匿名参与 TLS。换句话说,服务器接受他们的连接而不识别谁在尝试连接。这与相互 TLS 不同,其中服务器和客户端在完成握手之前相互验证。

The internet is a scary place and we want to protect our clients from connecting to spoofed public endpoints. We do this by ensuring our clients identify the server before sending any private data.

互联网是一个可怕的地方,我们希望保护我们的客户免于连接到欺骗性的公共端点。我们通过确保我们的客户在发送任何私人数据之前识别服务器来做到这一点。

// DO NOT DO THIS IF SHARING PRIVATE DATA WITH SERVICE
const httsAgent = new https.Agent({ rejectUnauthorized: false });

This is often posted (and more egregiously upvoted) as the answer on StackOverflow regarding https client connection failures in any language. And what's worse is that it usually works, unblocks the dev and they move on their merry way. However, while they certainly get in the door, whose door is it? Since they opted out of verifying the server's identity, their poor client has no way of knowing if the connection they just made to the company's intranet has bad actors listening on the line.

这通常作为 StackOverflow 上关于任何语言的 https 客户端连接失败的答案发布(并且更令人震惊地赞成)。更糟糕的是,它通常有效,解锁开发人员,他们继续他们的快乐方式。然而,虽然他们肯定进了门,但那是谁的门呢?由于他们选择不验证服务器的身份,他们可怜的客户端无法知道他们刚刚与公司内部网建立的连接是否有坏人在线上监听。

If the service has a public SSL cert, the https.Agentusually does not need to be configured further because your operating system provides a common set of publicly trusted CA certs. This is usually the same set of CA certs your browser is configured to use and is why a default axios client can hit https://google.comwith little fuss.

如果服务有公共 SSL 证书,https.Agent通常不需要进一步配置,因为您的操作系统提供了一组公共信任的 CA 证书。这通常是您的浏览器配置为使用的同一组 CA 证书,这也是默认 axios 客户端可以轻松访问https://google.com 的原因

If the service has a private SSL cert (self signed for testing purposes or one signed by your company's private CA to protect their internal secrets), the https agent must be configured to trust the private CA used to sign the server cert:

如果该服务具有私有 SSL 证书(出于测试目的自签名或由您公司的私有 CA 签名以保护其内部机密),则必须将 https 代理配置为信任用于签署服务器证书的私有 CA:

const httpsAgent = new https.Agent({ ca: MY_CA_BUNDLE });

where MY_CA_BUNDLEis an array of CA certs in .pemformat.

哪里MY_CA_BUNDLE.pem格式的 CA 证书数组。

回答by Fabio Espinosa

Create a custom agent with SSL certificate:

使用 SSL 证书创建自定义代理:

const httpsAgent = new https.Agent({
  rejectUnauthorized: false, // (NOTE: this will disable client verification)
  cert: fs.readFileSync("./usercert.pem"),
  key: fs.readFileSync("./key.pem"),
  passphrase: "YYY"
})

axios.get(url, { httpsAgent })

// or

const instance = axios.create({ httpsAgent })

From https://github.com/axios/axios/issues/284

来自https://github.com/axios/axios/issues/284

回答by mnhmilu

These configuration worked for me (In a Mutual Authentication scenario).

这些配置对我有用(在相互身份验证场景中)。

const httpsAgent = new https.Agent({
  ca: fs.readFileSync("./resource/bundle.crt"),        
  cert: fs.readFileSync("./resrouce/thirdparty.crt"),
  key: fs.readFileSync("./resource/key.pem"), 
})

Note: bundle.crt was prepared from provided certificates (root,intermediate,end entry certificate). Unfortunately no clear documentation found in this regards.

注意:bundle.crt 是根据提供的证书(根证书、中间证书、最终条目证书)准备的。不幸的是,在这方面没有找到明确的文件。