使用aiohttp复现CURL请求时遭遇SSLCertVerificationError求助
问题描述
我尝试用Python的aiohttp库复现一条能正常运行的CURL命令:
curl -k -X POST https://XXXXXXXXXXXXXXX.com \ --cert file.cer:pass \ --key file.key \ -u "XXXXXXXXXXX:XXXXXXXXXXX" \ -d "username=XXXXXXXXXXX" \ -d "password=XXXXXXXXXXX" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Basic XXXXXXXXXXX"
参考aiohttp文档创建了SSL上下文:
import ssl ssl_context = ssl.create_default_context() ssl_context.load_cert_chain( certfile=CERT_PATH, keyfile=KEY_PATH, password=KEY_PASS )
执行aiohttp请求的代码:
async with session.post(url,json=body,ssl=ssl_context) as r: ...
但运行时出现错误:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:997)
请问这是什么原因?
原因分析与解决方法
核心原因:未对应curl的
-k参数
curl的-k(或--insecure)作用是跳过SSL证书验证,但你用ssl.create_default_context()创建的上下文默认开启严格的证书校验,和curl的行为不一致,导致出现证书链验证失败的报错。额外潜在问题:请求格式不匹配
curl通过-d参数发送的是application/x-www-form-urlencoded格式的表单数据,但你用json=body发送的是JSON格式,这会自动把请求头的Content-Type改成application/json,和原curl命令的要求不符,可能引发服务端异常。修正后的代码示例
调整SSL上下文,关闭证书验证
import ssl ssl_context = ssl.create_default_context() # 加载客户端证书链 ssl_context.load_cert_chain( certfile=CERT_PATH, keyfile=KEY_PATH, password=KEY_PASS ) # 关闭证书验证,对应curl的-k参数 ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE
修正请求数据格式
将json=body替换为data=body,确保发送表单格式的数据:
# 构造表单结构的请求体 body = { "username": "XXXXXXXXXXX", "password": "XXXXXXXXXXX" } async with session.post(url, data=body, ssl=ssl_context) as r: response_text = await r.text() # 后续处理逻辑
另外注意:curl命令里的-u参数和手动设置的Authorization: Basic头是重复的(-u会自动生成Basic Auth头),实际使用时保留其中一种即可,避免冗余。
内容的提问来源于stack exchange,提问作者Dante Mogni
相关产品推荐
相关产品推荐

