调用Google API拉取Play报告报RefreshError:响应无访问令牌
核心错误
google.auth.exceptions.RefreshError: 'No access token in response.'
环境详情
- 操作系统类型及版本:未填写
- Python版本:3.9.0
- pip版本:22.0.4
google-api-python-client版本:2.48.0
问题描述
尝试拉取自有移动应用的Google Play Console报告(含安装量、异常报错等数据)时触发上述认证错误。最初参照官方操作手册实现但手册内容过时无法运行,后续参考社区方案调整代码适配当前版本Google API仍报错。
已完成的配置操作:
- 在GCP平台创建项目
- 创建服务账号(service account)
- 生成服务账号对应的JSON格式密钥文件
- 在Google Play Console平台邀请该服务账号,授予完整管理员权限(官方说明仅授予“查看应用信息、下载批量报告”权限即可满足需求)
- 在GCP IAM管理页面为该服务账号绑定"Storage Object Viewer"角色
- 已等待24小时,排除权限同步延迟导致异常的可能
(涉及项目、路径等敏感值已做匿名化处理)
复现代码
from googleapiclient.discovery import build from google.oauth2 import service_account scopes = ['https://www.googleapis.com/auth/devstorage.read_only','https://www.googleapis.com/auth/cloud-platform.read_only'] key_file_location = 'files/access_token/mykeyfile.json' cloud_storage_bucket = r'pubsite_prod_rev_00123456789' report_to_download = 'installs/installs_com.my.app_202201_country.csv' creds = service_account.Credentials.from_service_account_file(key_file_location,scopes=scopes) service = build('storage','v1', credentials=creds) print(service.objects().get(bucket = cloud_storage_bucket, object= report_to_download).execute())
错误堆栈
Traceback (most recent call last): File "C:\Users\myuser\project\z_10_ext_google_play_store.py", line 46, in <module> print(service.objects().get(bucket = cloud_storage_bucket, object= report_to_download).execute()) File "D:\Programs\Python\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper return wrapped(*args, **kwargs) File "D:\Programs\Python\lib\site-packages\googleapiclient\http.py", line 923, in execute resp, content = _retry_request( File "D:\Programs\Python\lib\site-packages\googleapiclient\http.py", line 191, in _retry_request resp, content = http.request(uri, method, *args, **kwargs) File "D:\Programs\Python\lib\site-packages\google_auth_httplib2.py", line 209, in request self.credentials.before_request(self._request, method, uri, request_headers) File "D:\Programs\Python\lib\site-packages\google\auth\credentials.py", line 133, in before_request self.refresh(request) File "D:\Programs\Python\lib\site-packages\google\oauth2\service_account.py", line 410, in refresh access_token, expiry, _ = _client.jwt_grant( File "D:\Programs\Python\lib\site-packages\google\oauth2\_client.py", line 199, in jwt_grant six.raise_from(new_exc, caught_exc) File "<string>", line 3, in raise_from google.auth.exceptions.RefreshError: ('No access token in response.', {'id_token': 'eyJ...'})
问题原因与解决方法
这个报错根本没走到存储桶权限校验环节,是在申请access token的阶段就失败了:接口只返回了id_token,没有返回预期的access_token,属于令牌请求参数不符合OAuth2接口要求导致的,按以下顺序排查修复即可:
- 修正scopes配置
你现在加的https://www.googleapis.com/auth/cloud-platform.read_only完全是多余的,还会干扰令牌签发逻辑。拉取Play Console存在GCS里的报告,只需要保留https://www.googleapis.com/auth/devstorage.read_only这一个scope就行;如果后续要调用Play Developer API的其他接口,可以额外加https://www.googleapis.com/auth/androidpublisher,不要乱加无关的scope。
修正后的配置:scopes = ['https://www.googleapis.com/auth/devstorage.read_only'] - 检查服务账号密钥文件是不是下错了
打开本地存的mykeyfile.json,确认文件里有"type": "service_account"、client_email、private_key这几个字段。如果文件里的type是authorized_user或者oauth_client,说明你下的不是服务账号密钥,要重新进入对应服务账号的详情页,在「密钥」标签下新建JSON格式的服务账号密钥重新下载。 - 删掉没用的IAM绑定
你在自己GCP项目IAM页给服务账号绑的Storage Object Viewer角色一点用都没有。pubsite_prod_rev_*开头的存储桶是Google Play官方托管的,根本不属于你个人的GCP项目,不认你自己项目里配的IAM权限,访问权限只认Play Console里给服务账号加的授权。自己项目里乱绑角色反而可能触发组织策略的scope限制,直接删掉这个绑定就行。 - 核对Play Console的授权配置
邀请服务账号的时候,别只给组织级权限,一定要选中你要拉取数据的对应应用,给服务账号开「查看应用信息、下载批量报告」的权限,加完权限不用等24小时,5-10分钟就能生效。
如果改完上面的配置还是报错,直接升级下google-auth相关依赖到最新版,规避旧版本的JWT请求参数bug:pip install --upgrade google-auth google-auth-httplib2 google-api-python-client
内容的提问来源于stack exchange,提问作者Aquen
相关产品推荐
相关产品推荐

