构建Google API资源遇'OAuth2Token'无'authorize'属性错误,已装依赖仍未解决
我来帮你搞定这个问题!你遇到的这个错误,核心原因是你传给build()方法的凭证格式不对——flow.fetch_token()返回的是一个字典,而google-api-python-client的build()需要的是一个Credentials对象,不是原始的字典数据。哪怕你装了google-auth-httplib2,这个类型不匹配的问题还是会存在。
咱们来看具体的修改方案:
步骤1:导入Credentials类
首先,你需要从google.oauth2.credentials模块导入Credentials类,用来把字典转换成合法的凭证对象。
步骤2:转换凭证格式
把flow.fetch_token()得到的字典,转换成Credentials实例,再传给build()方法。另外,为了后续能刷新凭证,建议你把凭证的信息(比如刷新令牌、客户端ID等)保存下来,方便下次使用。
修改后的代码如下:
from google.oauth2.credentials import Credentials # 新增导入 class Oauth2CallbackView(View): def get(self, request, *args, **kwargs): flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) flow.redirect_uri = 'http://127.0.0.1:8000/profiles/oauth2callback/' # 获取字典格式的凭证 token_dict = flow.fetch_token(code=self.request.GET.get('code')) # 转换成Credentials对象 credentials = Credentials( token_dict['access_token'], refresh_token=token_dict.get('refresh_token'), token_uri=flow.client_config['token_uri'], client_id=flow.client_config['client_id'], client_secret=flow.client_config['client_secret'], scopes=SCOPES ) # 现在可以正常调用build了 b = build(API_SERVICE_NAME, API_VERSION, credentials=credentials) # 可选:把credentials保存到session或数据库,方便后续使用 request.session['credentials'] = credentials_to_dict(credentials) return redirect('http://127.0.0.1:8000/profiles/') # 辅助函数:把Credentials对象转换成可序列化的字典(可选) def credentials_to_dict(credentials): return { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes }
为什么之前装了google-auth-httplib2还是报错?
google-auth-httplib2是用来让google-auth和httplib2配合工作的适配器,但你的问题根本不是适配器的问题,而是传入的凭证类型不对——你传了字典,而不是Credentials对象,所以这个库的存在与否不影响这个错误的出现。
额外检查
从你的pip freeze输出看,你的依赖版本都是兼容的:
google-api-python-client==1.7.9google-auth==1.6.3google-auth-httplib2==0.0.3
这些版本搭配起来是没问题的,所以只要修改代码里的凭证转换逻辑就能解决问题。
内容的提问来源于stack exchange,提问作者Michael Ninh




