使用LIBCURL(C语言)实现Bearer Token授权GET请求遇SSL错误求助
看起来你遇到的问题主要是两个核心点:错误禁用了SSL导致协议不匹配,以及证书验证失败。我帮你一步步拆解问题并给出解决方案:
首先定位核心错误:禁用SSL导致的协议不兼容
你代码里加了这一行:
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_NONE);
这是致命错误!因为HTTPS连接必须依赖SSL/TLS握手,设置CURLUSESSL_NONE会强制curl用普通HTTP协议去连接443端口,而服务器期望的是SSL协议握手,自然会返回SSL23_GET_SERVER_HELLO:unknown protocol错误。必须删掉这一行!
修正URL格式避免协议解析问题
你的URL没有带https://前缀,虽然设置了CURLOPT_DEFAULT_PROTOCOL,但部分旧版本的libcurl可能对这个选项支持不好,直接在URL里指定协议更可靠。另外,URL里的&是HTML转义符,代码里直接用&即可:
curl_easy_setopt(curl, CURLOPT_URL, "https://abcxyz.com/v1/service-invenue/configs?keys=SSC_AVAILABLE&keys=SSC_AVAILABLE");
强制指定TLS版本解决兼容性
如果你的libcurl或依赖的OpenSSL版本较旧,默认的SSL/TLS协议版本可能不被服务器支持(比如服务器只允许TLS1.2及以上),可以强制指定版本:
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // 如果服务器支持TLS1.3,也可以改成CURL_SSLVERSION_TLSv1_3
处理证书验证失败的问题
Python代码里的CERTIFICATE_VERIFY_FAILED说明服务器的证书不在客户端的信任根列表里,这里分两种场景处理:
测试环境(临时方案)
可以临时关闭证书验证(生产环境绝对禁用此方式),你已经加了这两个选项,确保它们在设置URL之后生效:
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
生产环境(正确方案)
下载服务器的CA证书(可以从浏览器导出,或者联系服务方获取),然后指定证书路径:
curl_easy_setopt(curl, CURLOPT_CAINFO, "/绝对路径/到/你的/ca-cert.pem");
优化Bearer Token的设置
你手动构造Authorization头是可行的,不过libcurl提供了更规范的方式来设置Bearer Token,避免手动拼接错误:
curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "5065157d2873736ddd726df6678ddh972413");
用这个选项的话,就不需要手动创建HTTP头了,libcurl会自动处理Authorization字段。
修正后的完整C代码片段
#include <curl/curl.h> #include <stdio.h> int main(void) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { // 设置GET请求和正确的HTTPS URL curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); curl_easy_setopt(curl, CURLOPT_URL, "https://abcxyz.com/v1/service-invenue/configs?keys=SSC_AVAILABLE&keys=SSC_AVAILABLE"); // 跟随重定向(如果需要) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // 强制使用TLS1.2适配服务器要求 curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // 测试环境临时关闭证书验证(生产环境替换为CURLOPT_CAINFO) curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); // 设置Bearer Token(替代手动构造Authorization头) curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "5065157d2873736ddd726df6678ddh972413"); // 执行请求 res = curl_easy_perform(curl); if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); // 清理资源 curl_easy_cleanup(curl); } return 0; }
附带:Python代码的修复方案
如果只是测试用,可以关闭证书验证:
import http.client import ssl conn = http.client.HTTPSConnection("abcxyz.com", context=ssl._create_unverified_context()) payload = '' headers = { 'Authorization': 'Bearer 5065157d2873736ddd726df6678ddh972413' } conn.request("GET", "/v1/service-invenue/configs?keys=SSC_AVAILABLE&keys=SSC_AVAILABLE", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))
生产环境同样需要指定CA证书路径:
import http.client import ssl context = ssl.create_default_context(cafile="/path/to/ca-cert.pem") conn = http.client.HTTPSConnection("abcxyz.com", context=context) # 后续代码同上
内容的提问来源于stack exchange,提问作者SajithP

