使用带认证的reqwest请求报证书错误时如何获取响应正文
问题根因
报错里明确提示The certificate was not trusted,故障出在TLS握手阶段,和HTTP请求头、账号密码认证逻辑完全无关。本地默认部署的Elasticsearch启用HTTPS时会使用自生成的签名证书,这类证书不在reqwest默认的可信证书列表内,所以连接会被直接拦截,根本不会走到后续的身份校验流程,你之前手动构造Authorization请求头的操作属于找错了故障点,自然无法解决问题。
解决方案
根据使用场景二选一即可:
- 本地开发/测试环境快速验证:关闭证书校验
构建reqwest客户端时开启无效证书接受配置即可快速跑通逻辑,修改后的可运行代码如下:
use reqwest::Client; #[tokio::main] async fn main() { let health = get_health().await; } async fn get_health() { let client = Client::builder() .danger_accept_invalid_certs(true) .build() .expect("客户端构建失败"); let res = client .get("https://localhost:9200/speaker") .basic_auth("elastic", Some("7*7C68392TXAENxKRot")) .send() .await .expect("请求发送失败") .text() .await .expect("响应内容读取失败"); println!("{}", res); }
警告:该配置会跳过所有TLS证书校验,存在中间人攻击风险,绝对不能在生产环境使用。
- 生产环境合规方案:加载Elasticsearch自签CA证书到信任链
从Elasticsearch部署路径下找到自带的CA证书(默认路径为config/certs/http_ca.crt),构建客户端时将该证书加入可信根证书列表,既可以解决证书不信任问题,又不会降低TLS安全性,代码示例如下:
use reqwest::Client; use std::fs; #[tokio::main] async fn main() { let health = get_health().await; } async fn get_health() { // 读取Elasticsearch本地CA证书文件 let ca_content = fs::read("/你的Elasticsearch部署路径/config/certs/http_ca.crt") .expect("CA证书读取失败"); let ca_cert = reqwest::Certificate::from_pem(&ca_content).expect("CA证书格式解析失败"); let client = Client::builder() .add_root_certificate(ca_cert) .build() .expect("客户端构建失败"); let res = client .get("https://localhost:9200/speaker") .basic_auth("elastic", Some("7*7C68392TXAENxKRot")) .send() .await .expect("请求发送失败") .text() .await .expect("响应内容读取失败"); println!("{}", res); }
不需要手动构造Authorization请求头,reqwest内置的
basic_auth方法会自动生成符合规范的认证请求头,手动重复写入反而可能引发请求头冲突。
内容的提问来源于stack exchange,提问作者Xavi Font
相关产品推荐
相关产品推荐

