我正在尝试使用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以信任证书并正确验证它?
答案 0 :(得分:14)
古老的问题,但为那些降落在这里的人迷住了。没有专家。请咨询您当地的安全专家,否则不可以。
Axios是一个http(s)客户端,并且http客户端通常匿名参与TLS。换句话说,服务器接受他们的连接,而不标识谁在尝试连接。这与互助TLS(Mutual TLS)不同,在服务器和客户端之间完成握手之前,相互验证。
互联网是一个令人恐惧的地方,我们希望保护我们的客户免于连接到欺骗性的公共端点。为此,我们确保客户在发送任何私有数据之前先识别服务器。
// DO NOT DO THIS IF SHARING PRIVATE DATA WITH SERVICE
const httsAgent = new https.Agent({ rejectUnauthorized: false });
这经常被发布(并且更令人发指),作为关于任何语言的https客户端连接失败的StackOverflow的答案。更糟糕的是,它通常可以正常工作,可以解除开发人员的封锁,而他们会以快乐的方式前进。但是,尽管他们一定进入了门,但它是谁的门?由于他们选择不验证服务器的身份,因此可怜的客户端无法知道他们刚刚与公司Intranet建立的连接是否有不良行为者在监听。
如果服务具有公共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
是.pem
格式的一系列CA证书。
答案 1 :(得分:3)
使用SSL证书创建自定义代理:
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
cert: fs.readFileSync("./usercert.pem"),
key: fs.readFileSync("./key.pem"),
passphrase: "YYY"
})
axios.get(url, { httpsAgent })
// or
const instance = axios.create({ httpsAgent })
答案 2 :(得分:2)
对我来说,当我的应用程序在开发模式下运行时,我直接在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.options = httpsAgent
// eslint-disable-next-line no-console
console.log(process.env.NODE_ENV, `RejectUnauthorized is disabled.`)
}
答案 3 :(得分:0)
这些配置对我有用(在相互认证的情况下)。
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是从提供的证书(根,中间,结束条目证书)准备的。不幸的是,在这方面没有明确的文档。
答案 4 :(得分:0)
这对我有用,使用 axios 和 nodejs + express
exports.test_ssl = async (req,res) => {
let cert_file = fs.readFileSync("./ssl/my_self_signed_certificate.crt")
const agent = new https.Agent({
requestCert: true,
rejectUnauthorized: false,
cert: cert_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
});
}
答案 5 :(得分:-4)
亲爱的早上好。
我的问题如下:
“启用验证第一个证书”,错误代码为“ENABLE_TO_VERIFY_LEAF_SIGNATURE”。
他们给我发送了一个扩展名为 .pfx 的证书,并使用以下命令生成了 .pem 证书和带有 .pem 扩展名的密钥。
我附上了命令。
需要注意的是,我使用 axios 发出请求。
我在 axios 中附加了我的代理配置。
const httpsAgent = 新的 https.Agent ({
pfx: fs.readFileSync ("path.pfx"),
密码:'密码',
请求证书:真实,
拒绝未授权:真
});