如何解决Python调用Google Sheets API时的403权限不足问题
问题描述
在MacOS Monterey+VSCode环境下开发Python脚本,目标是通过短期联合身份令牌下载个人账号的Google表格,后续计划迁移到Minikube等环境。目前已完成以下操作:
- 开启Sheets API
- 获取客户端ID与密钥
- 安装Google CLI并执行
gcloud auth application-default login
但调用API时触发403错误,提示**"Request had insufficient authentication scopes"**。
当前代码
""" BEFORE RUNNING: --------------- 1. If not already done, enable the Google Sheets API and check the quota for your project at https://console.developers.google.com/apis/api/sheets 2. Install the Python client library for Google APIs by running `pip install --upgrade google-api-python-client` """ from pprint import pprint from googleapiclient import discovery # TODO: Change placeholder below to generate authentication credentials. See # https://developers.google.com/sheets/quickstart/python#step_3_set_up_the_sample # # Authorize using one of the following scopes: # 'https://www.googleapis.com/auth/drive' # 'https://www.googleapis.com/auth/drive.file' # 'https://www.googleapis.com/auth/drive.readonly' # 'https://www.googleapis.com/auth/spreadsheets' # 'https://www.googleapis.com/auth/spreadsheets.readonly' credentials = None service = discovery.build('sheets', 'v4', credentials=credentials) # The ID of the spreadsheet to retrieve data from. spreadsheet_id = '' # TODO: Update placeholder value. # The A1 notation of the values to retrieve. range_ = 'A1:Y1' # TODO: Update placeholder value. # How values should be represented in the output. # The default render option is ValueRenderOption.FORMATTED_VALUE. value_render_option = '' # TODO: Update placeholder value. # How dates, times, and durations should be represented in the output. # This is ignored if value_render_option is # FORMATTED_VALUE. # The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER]. date_time_render_option = '' # TODO: Update placeholder value. # request = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range_, valueRenderOption=value_render_option, dateTimeRenderOption=date_time_render_option) # response = request.execute() # errors here from above request = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range_) response = request.execute() # TODO: Change code below to process the `response` dict: pprint(response)
错误信息
raise HttpError(resp, content, uri=self.uri) googleapiclient.errors.HttpError: <HttpError 403 when requesting https://sheets.googleapis.com/v4/spreadsheets/1234567long_spreadsheet_id/values/A1%3AY1?alt=json returned "Request had insufficient authentication scopes.". Details: "[{'@type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', 'domain': 'googleapis.com', 'metadata': {'service': 'sheets.googleapis.com', 'method': 'google.apps.sheets.v4.SpreadsheetsService.GetValues'}}]"
解决方案
修复凭据加载与权限范围配置
原代码中credentials = None的写法完全错误,需要补充凭据加载逻辑,并确保权限范围正确。先安装完整的依赖包:pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client修改代码中的凭据部分:
from google.auth.transport.requests import Request import google.auth # 根据需求选权限,只读表格用spreadsheets.readonly,可编辑用spreadsheets SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'] # 加载gcloud登录生成的应用默认凭据,并附加指定权限 credentials, project_id = google.auth.default(scopes=SCOPES) # 自动刷新过期令牌 if credentials.expired and credentials.refresh_token: credentials.refresh(Request())重新登录并指定权限范围
之前的gcloud auth application-default login没指定权限,导致生成的令牌权限不够。重新执行登录命令:gcloud auth application-default login --scopes=https://www.googleapis.com/auth/spreadsheets.readonly,https://www.googleapis.com/auth/drive.readonly权限范围按需调整,比如需要访问Drive内的表格就加上Drive相关权限。
Minikube环境适配建议
迁移到K8s环境时,不要用本地登录凭据,改用工作负载身份:- 创建K8s服务账户,绑定到Google Cloud的服务账户
- 给Google Cloud服务账户授予Sheets相关角色(比如
roles/sheets.reader) - 在Pod配置中添加工作负载身份注解,系统会自动生成并刷新短期令牌
验证权限是否生效
用以下命令检查当前令牌的权限范围:gcloud auth application-default print-access-token | xargs curl -H "Authorization: Bearer {}" https://www.googleapis.com/oauth2/v3/tokeninfo查看返回的
scope字段,确认包含你需要的权限。
内容的提问来源于stack exchange,提问作者roland garceau
相关产品推荐
相关产品推荐

