You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 2.7使用oauth2client获取GCP认证令牌时遇SSL错误

Python 2.7下使用oauth2client获取GCP Bearer令牌报错的解决方法及替代方案

问题背景

由于google-auth库不支持Python 2.7,需使用oauth2client复现google-auth的令牌获取逻辑,但运行代码时出现错误:cannot set verify_mode to CERT_NONE when check_hostname is enable。

报错原因

该错误是因为httplib2在启用disable_ssl_certificate_validation=True时,仅将SSL验证模式设为CERT_NONE,但未关闭check_hostname,两者冲突导致报错。


解决方案1:手动配置SSL上下文修复httplib2问题

直接创建自定义SSL上下文,同时关闭check_hostname和证书验证,替代httplib2自带的参数:

from oauth2client.service_account import ServiceAccountCredentials
import httplib2
import ssl

def get_token(serviceAccountPath, authTarget, proxy_url, proxy_port):
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        serviceAccountPath, scopes=[authTarget]
    )
    # 创建自定义SSL上下文,同时关闭主机名检查和证书验证
    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
    ssl_context.check_hostname = False
    ssl_context.verify_mode = ssl.CERT_NONE
    
    # 初始化Http对象,传入自定义SSL上下文和代理信息
    http = httplib2.Http(
        proxy_info=httplib2.ProxyInfo(
            httplib2.socks.PROXY_TYPE_HTTP,
            proxy_url,
            proxy_port
        ),
        ssl_context=ssl_context
    )
    
    http_auth = credentials.authorize(http)
    credentials.refresh(http_auth.request)
    return credentials.access_token

解决方案2:改用requests作为传输层

和google-auth的实现逻辑对齐,用requests替代httplib2,通过自定义适配器解决SSL验证问题:

from oauth2client.service_account import ServiceAccountCredentials
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
import ssl

class SSLNoVerifyAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        # 创建禁用证书验证和主机名检查的SSL上下文
        context = create_urllib3_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
        kwargs['ssl_context'] = context
        super(SSLNoVerifyAdapter, self).init_poolmanager(*args, **kwargs)

def get_token(serviceAccountPath, authTarget, proxy_url, proxy_port):
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        serviceAccountPath, scopes=[authTarget]
    )
    
    # 配置requests会话,设置代理
    session = requests.Session()
    session.proxies = {
        'http': f'http://{proxy_url}:{proxy_port}',
        'https': f'http://{proxy_url}:{proxy_port}'
    }
    # 挂载自定义适配器,处理HTTPS请求的SSL验证
    session.mount('https://', SSLNoVerifyAdapter())
    
    # 使用session的request方法完成令牌刷新
    credentials.refresh(session.request)
    return credentials.access_token

替代方案:调用gcloud命令行工具获取令牌

如果环境已安装Google Cloud SDK(gcloud),可以直接调用命令行工具获取令牌,无需依赖oauth2client:

import subprocess

def get_token_via_gcloud():
    # 调用gcloud命令获取默认应用凭据的访问令牌
    token_result = subprocess.check_output(
        ['gcloud', 'auth', 'application-default', 'print-access-token'],
        stderr=subprocess.STDOUT
    )
    # 处理输出,返回纯令牌字符串
    return token_result.strip().decode('utf-8')

注意事项

  • 需确保环境已配置gcloud,且默认应用凭据有效(可通过gcloud auth application-default login或设置GOOGLE_APPLICATION_CREDENTIALS环境变量完成配置)。

内容的提问来源于stack exchange,提问作者JayEstrera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:45:41