You need to enable JavaScript to run this app. Python对接Google Sheets API刷新token抛invalid_scope错误求助
优惠活动
大模型
产品
解决方案
定价
更多

Python对接Google Sheets API刷新token抛invalid_scope错误求助

报错根因

invalid_scope 错误的触发逻辑非常明确:调用token刷新接口时,请求携带的scope参数,与Google侧记录的该refresh_token实际授权过的scope列表不匹配,直接被OAuth服务拒绝。
结合给出的代码逻辑,触发这类问题的常见诱因分为三类:

  • 代码中定义的SCOPES列表,与本地token_spread.json存储的已授权scope存在差异
  • 核心OAuth依赖版本错位,导致刷新请求传递的scope参数格式不符合接口要求
  • Google Cloud侧的OAuth配置与当前使用的scope不匹配
排查与解决方案

1. 优先核对scope一致性

绝大多数该类报错都源于scope不匹配:

  • 直接打开项目根目录下的token_spread.json文件,找到内部的scopes字段,逐字符对比与代码中硬编码的SCOPES列表是否完全一致:
    • 检查是否存在URL拼写偏差(如将spreadsheets错写为单数形式、多/末尾少斜杠)
    • 检查是否夹带不可见字符(换行、多余空格等)
    • 检查是否存在scope条目增减(如代码新增了其他服务的scope,但未重新走授权流程)
  • 如果发现不一致,直接删除本地token_spread.json文件,重新运行程序走一次手动授权流程,生成与当前代码scope完全匹配的新token文件。新token生成后,刷新逻辑会与Google侧记录的授权范围完全对齐,不会再触发scope校验错误。

2. 排查依赖版本兼容问题

旧版本google-auth-oauthlib存在已知bug,会在刷新请求时对scopes参数做错误拼接,触发Google侧的参数校验失败。

  • 检查当前环境下三个核心依赖的版本:
    • google-api-python-client
    • google-auth
    • google-auth-oauthlib
  • 升级三类依赖到与Python 3.8.5兼容的最新稳定版本,规避旧版本的参数拼接bug。

3. 校验Google Cloud侧配置

  • 对照当前使用的credentials.json,确认对应的Google Cloud项目内:
    • 该OAuth客户端绑定的同意屏配置中,已添加代码中使用的Sheets读写scope
    • 如果应用处于测试状态,需确认运行授权的Google账号已被添加为测试用户,避免scope授权不生效
  • 长期无人值守场景注意:测试状态的外部OAuth应用,生成的refresh_token默认仅7天有效;将应用正式发布后,可获取长期有效的refresh_token,无需定期重新授权。

4. 优化授权逻辑规避同类问题

原代码中从token文件加载凭证时强制传入全局SCOPES的逻辑,会在后续调整scope时强制触发刷新请求携带新scope,可做如下优化:

  • 加载凭证时优先读取token文件中自带的scopes,仅在首次生成token时使用硬编码的SCOPES发起授权
  • 后续需要调整scope范围时,主动删除旧token文件,走一次手动授权流程更新token的授权范围
稳定版优化代码
from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials

def service_spread():
    """
    Creates token for spreadsheet with required authorisation.
    Returns required service.
    """
    SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
    creds = None
    if os.path.exists('token_spread.json'):
        # 加载凭证时不强制传入硬编码SCOPES,优先复用文件中存储的已授权scope
        creds = Credentials.from_authorized_user_file('token_spread.json')
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # 保存最新凭证到本地
        with open('token_spread.json', 'w') as token:
            token.write(creds.to_json())

    return build('sheets', 'v4', credentials=creds)

注意:调整scope后必须删除旧token文件,重新走授权流程生成新token,否则仍会因为scope不匹配触发刷新错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 13:45:03