curl可正常获取Token但Python requests报SSL证书验证失败的问题求助
curl可正常获取Token但Python requests报SSL证书验证失败的问题求助
首先,我注意到几个可能导致这个问题的点,咱们一步步排查:
1. SSL证书信任差异:curl和requests的证书存储不同
curl默认会使用系统的根证书存储(RHEL8上是/etc/pki/tls/certs/ca-bundle.crt),但requests在搭配pyOpenSSL使用时,可能没正确识别系统根证书,或者读取的证书源和curl不同。
你可以先试试让requests强制使用系统根证书,修改请求代码,指定verify参数为系统证书路径:
# 替换原请求行,指定RHEL8默认系统CA证书路径 r = requests.post( url=url, headers=headers, data=data, timeout=(30,30), verify="/etc/pki/tls/certs/ca-bundle.crt" )
如果这样能解决,说明Python的requests没有默认加载系统根证书,是环境配置的问题。
2. curl和Python脚本的请求参数不一致
仔细对比后发现两处关键参数不匹配:
- grant_type值不同:curl里是
operator_password,Python脚本里写的是password - 认证方式不同:curl用
-u client_id:client_secret做Basic Auth(自动生成Authorization请求头),而Python脚本是把client_id/secret放到了表单数据里
这两个差异即使暂时没触发报错,后续也会导致认证失败,建议先统一成和curl一致的请求逻辑:
import requests client_id = "client_id" client_secret = "client_secret" username = "client_id" password = "password" brand = 'BRAND' url = 'https://rest_server/rest-api-auth/oauth/token' headers = {'accept': "application/json"} # 修正grant_type,移除表单里的client_id/secret data = { 'grant_type': 'operator_password', 'username': username, 'password': password, 'brand_key': brand, } try: # 用auth参数实现curl的-u Basic Auth逻辑 r = requests.post( url=url, headers=headers, data=data, timeout=(30,30), auth=(client_id, client_secret), verify="/etc/pki/tls/certs/ca-bundle.crt" ) print(r.content) except requests.exceptions.HTTPError as errh: print(f"Http Error: {errh}") except requests.exceptions.ConnectionError as errc: print(f"Error Connecting: {errc}") except requests.exceptions.Timeout as errt: print(f"Timeout Error: {errt}") except requests.exceptions.RequestException as err: print(f"RequestException Error: {err}")
3. 临时排查:跳过SSL验证(仅用于测试,生产禁用)
如果上面的方法都不行,可以临时禁用SSL验证来确认是不是证书信任的问题(注意:生产环境绝对不能这么做,会有安全风险):
# 在请求里添加verify=False r = requests.post( url=url, headers=headers, data=data, timeout=(30,30), auth=(client_id, client_secret), verify=False )
如果这样能成功请求,那100%是证书信任的问题,回到第一个方案,确保requests能加载到正确的信任证书。
4. 检查服务器证书链是否完整
有些服务器的SSL证书需要搭配中间证书才能被正确验证,curl可能会自动补全证书链,但requests在某些环境下不会。你可以用curl -v https://rest_server查看证书链信息,如果发现中间证书缺失,把完整的证书链(根证书+中间证书+服务器证书)合并成一个文件,让requests的verify参数指向这个文件即可。
总结下来,先统一请求参数和认证方式,再排查SSL证书信任的问题,应该就能解决了。
备注:内容来源于stack exchange,提问作者urosdigital
相关产品推荐
相关产品推荐

