简体   繁体   English

如何配置 axios 使用 SSL 证书?

[英]How to configure axios to use SSL certificate?

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 以信任证书并正确验证它?

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. Axios 是一个 http(s) 客户端,http 客户端通常匿名参与 TLS。 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.这与说相互 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 httpsAgent = 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.这通常作为 StackOverflow 上关于任何语言的 https 客户端连接失败的答案发布(并且受到更多人的反对)。 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.由于他们选择不验证服务器的身份,他们可怜的客户无法知道他们刚刚与公司内部网建立的连接是否有不良行为者在线监听。

If the service has a public SSL cert, the https.Agent usually does not need to be configured further because your operating system provides a common set of publicly trusted CA certs.如果服务具有公共 SSL 证书,则通常不需要进一步配置https.Agent ,因为您的操作系统提供了一组公共受信任的 CA 证书。 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.com with little fuss.这通常是您的浏览器配置使用的同一组 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_BUNDLE is an array of CA certs with both the server cert for the endpoint you want to hit and that cert's complete cert chain in .pem format.其中MY_CA_BUNDLE是一个 CA 证书数组,其中包含您要访问的端点的服务器证书和.pem格式的该证书的完整证书链。 You must include all certs in the chain up to the trust root.您必须将链中的所有证书包括到信任根。


Where are these options documented?这些选项记录在哪里?

HTTPS is the HTTP protocol over TLS/SSL. HTTPS 是基于 TLS/SSL 的 HTTP 协议。 In Node.js this is implemented as a separate module.在 Node.js 中,这是作为一个单独的模块实现的。

Therefore options passed to the https.Agent are a merge of the options passed to tls.connect() and tls.createSecureContext() .因此传递给https.Agent的选项是传递给tls.connect()tls.createSecureContext()的选项的合并。

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

For me, when my application is running in development mode, I have disabled rejectUnauthorized directly in axios.defaults.options .对我来说,当我的应用程序在开发模式下运行时,我直接在axios.defaults.options rejectUnauthorized This works very well.这很好用。 be careful and use this only in developer mode.小心并仅在开发人员模式下使用它。

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.`)
}

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).注意:bundle.crt 是根据提供的证书(根证书、中间证书、最终入口证书)准备的。 Unfortunately no clear documentation found in this regards.不幸的是,在这方面没有找到明确的文件。

This is very dirty, but at the top of your script, just put:这很脏,但是在脚本的顶部,只需输入:

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

This basically tells node to not check SSL certificates, which is very convenient when you get self signed certificates rejected in development.这基本上告诉节点不要检查 SSL 证书,当您在开发中遇到自签名证书被拒绝时,这非常方便。

Please don't use this in production.请不要在生产中使用它。

This what worked for me , using axios with nodejs + express这对我有用,将axios与nodejs + express一起使用

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,
    cert: cert_file,
    ca: ca_file
});
const options = {
    url: `https://51.195.45.154/test`,  // <---this is  a fake ip do not bother
    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
});

}

This worked for me:这对我有用:

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

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 });

This is what work for me.这对我有用。

Good afternoon,下午好,

I was having the same issue and I managed to work around using the following code:我遇到了同样的问题,我设法使用以下代码解决了这个问题:

const https = require('https');
var axios = require("axios").default;

const Agent = new https.Agent({
rejectUnauthorized: false
})

async function ABC(text) {
var detect = {
method: 'POST',
url: URL + '/Detect',
params: {'api-version': '3.0'},
httpsAgent: Agent,
headers: headers,
data: [{Text: text}]
};

await axios.request(ABC).then(function (response) { CODE HERE })
.catch((er)=>{
console.log(er)
 }
});

Good morning dear.早上好亲爱的。

My problem is the following:我的问题如下:

"Enable to verify the first certificate" with an error code 'ENABLE_TO_VERIFY_LEAF_SIGNATURE'. “启用验证第一个证书”,错误代码为“ENABLE_TO_VERIFY_LEAF_SIGNATURE”。

They sent me a certificate with a .pfx extension and with the following commands I generated the .pem certificate and the key also with a .pem extension.他们向我发送了带有 .pfx 扩展名的证书,并使用以下命令生成了 .pem 证书和带有 .pem 扩展名的密钥。

I attach the commands.我附上命令。

  • openssl pkcs12 -in certificate.pfx -nocerts -out key.pem -nodes openssl pkcs12 -in certificate.pfx -nocerts -out key.pem -nodes
  • openssl pkcs12 -in certificate.pfx -nokeys -out certificate.pem openssl pkcs12 -in certificate.pfx -nokeys -out certificate.pem

It should be noted that I am using axios to make the request.需要注意的是,我是使用 axios 来发出请求的。

I attach my agent configuration in axios.我在 axios 中附加了我的代理配置。

const httpsAgent = new https.Agent ({常量 httpsAgent = 新的 https.Agent ({
pfx: fs.readFileSync ("path.pfx"), passphrase: 'password', requestCert: true, rejectUnauthorized: true }); pfx: fs.readFileSync ("path.pfx"), passphrase: 'password', requestCert: true, rejectUnauthorized: true });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM