NodeJS 如何配置axios使用SSL证书?

xnifntxz  于 2023-03-22  发布在  Node.js
关注(0)|答案(8)|浏览(757)

我尝试使用axios向API端点发出请求,并收到以下错误:Error: unable to verify the first certificate
axios使用的https模块似乎无法验证服务器上使用的SSL证书。
当我用浏览器访问服务器时,证书是有效的,我可以看到/下载它。我也可以通过https向浏览器上的API发出请求。
我可以通过关闭验证来解决这个问题。这段代码有效。

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

问题是,这不会验证SSL证书,因此会打开安全漏洞。
如何配置axios以信任证书并正确验证它?

jexiocij

jexiocij1#

老问题,但插话为那些谁在这里降落。没有Maven。请咨询您当地的安全大师和什么不。
Axios是一个http(s)客户端,http客户端通常匿名参与TLS。换句话说,服务器接受他们的连接,而不识别谁正在尝试连接。这与双向TLS不同,在双向TLS中,服务器和客户端在完成握手之前都要互相验证。
互联网是一个可怕的地方,我们希望保护我们的客户端连接到欺骗的公共端点。我们通过确保我们的客户端在发送任何私人数据之前识别服务器来实现这一点。

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

这是经常张贴的(而且更令人震惊的是)作为StackOverflow上关于任何语言的https客户端连接失败的答案。更糟糕的是,它通常有效,解除了开发人员的封锁,他们继续他们的快乐之路。然而,虽然他们肯定进入了大门,但这是谁的门?因为他们选择了不验证服务器的身份,他们可怜的客户没有办法知道他们刚刚建立的到公司内部网的连接是否有坏人在监听线路。
如果服务有公共SSL证书,则https.Agent通常不需要进一步配置,因为您的操作系统提供了一组公共可信的CA证书。这通常与您的浏览器配置使用的CA证书相同,这就是为什么默认的axios客户端可以轻松访问https://google.com
如果服务具有私有SSL证书(出于测试目的进行自签名,或由公司的私有CA签名以保护其内部机密),则必须将https代理配置为信任用于签署服务器证书的私有CA:

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

其中,MY_CA_BUNDLE是CA证书的数组,其中包含您要访问的端点的服务器证书以及该证书的完整证书链(.pem)。您必须包括链中的所有证书,直到信任根。

这些选项的文档在哪里?

HTTPS是基于TLS/SSL的HTTP协议。在Node.js中,它是作为一个单独的模块实现的。
因此,传递给https.Agent的选项是传递给tls.connect()tls.createSecureContext()的选项的合并。

bfnvny8b

bfnvny8b2#

使用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 })

https://github.com/axios/axios/issues/284开始

3hvapo4f

3hvapo4f3#

对我来说,当我的应用程序在开发模式下运行时,我已经直接在axios.defaults.options中禁用了rejectUnauthorized,这工作得很好,要小心,只在开发者模式下使用这个。

import https from 'https'
import axios from 'axios'
import config from '~/config'

/**
 * Axios default settings
 */
axios.defaults.baseURL = config.apiURL

/**
 * Disable only in development mode
 */
if (process.env.NODE_ENV === 'development') {
  const httpsAgent = new https.Agent({
    rejectUnauthorized: false,
  })
  axios.defaults.httpsAgent = httpsAgent
  // eslint-disable-next-line no-console
  console.log(process.env.NODE_ENV, `RejectUnauthorized is disabled.`)
}
o2g1uqev

o2g1uqev4#

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

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

注意:bundle.crt是根据提供的证书(根证书、中间证书、最终入口证书)编写的。不幸的是,在这方面没有找到明确的文档。

mtb9vblg

mtb9vblg5#

这是非常肮脏的,但在你的脚本的顶部,只是把:
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
这基本上是告诉node不要检查SSL证书,当你在开发中获得被拒绝的自签名证书时,这非常方便。
请不要在生产中使用它。

j7dteeu8

j7dteeu86#

这就是我所做的,在nodejs + express中使用axios

exports.test_ssl = async (req,res) => { 
       
    let cert_file = fs.readFileSync("./ssl/my_self_signed_certificate.crt")
    let ca_file = fs.readFileSync("./ssl/my_self_signed_certificate_ca.crt")
    const agent = new https.Agent({
        requestCert: true,
        rejectUnauthorized: true, // not for production
        cert: cert_file,
        ca: ca_file
    });
    const options = {
        url: `https://example.com/test`,
        method: "POST",
        httpsAgent: agent,
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/txt;charset=UTF-8'
        },
        data: {}
    };
    
    console.log(cert_file.toString())

    axios(options).then(response => {
        payload = response.data ;
        return res.status(200).send({"status":1});
    }).catch(err => {
        console.log(err);
        return false
    });

}
2fjabf4q

2fjabf4q7#

这对我很有效:

import axios from 'axios'
import https from 'https'

const headers = {};

const httpsAgent = new https.Agent({
  ca: fs.readFileSync('./certs/cert.pem'),
  cert: fs.readFileSync('./certs/cert.pem'),
})

const data = await axios.get(url, { httpsAgent, headers })
ttp71kqs

ttp71kqs8#

const https = require('https');
const axios = require('axios')

const CA = "-----BEGIN CERTIFICATE-----$$$$$-----END CERTIFICATE-----"
const url = "bla"
const httpsAgent = new https.Agent({
  ca: CA
});

const response = await axios.get(url, { httpsAgent });

这就是我的工作。

相关问题