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

为何Google Drive令牌自动续期代码失效,需重复授权?

问题诊断与修复方案

常见导致invalid_grant错误的原因及解决方法

1. 刷新令牌已失效或被撤销

Google OAuth2的刷新令牌并非永久有效,尤其是桌面应用类型的令牌,以下情况会导致其失效:

  • 用户修改了Google账号密码
  • 刷新令牌超过6个月未被使用(即使你每半小时执行代码,也可能刷新操作未真正触发)
  • 用户在Google账号「安全」页面手动撤销了该应用的权限
  • 同一客户端ID下,同一用户生成的刷新令牌数量超过25个(旧令牌会被自动撤销)

解决:

  • 检查用户账号是否修改过密码、是否撤销过应用权限,恢复权限后重新授权
  • 避免频繁触发新授权流程(比如每次运行都跳过刷新直接走授权),防止超过令牌数量限制

2. 代码逻辑的潜在问题

你的代码框架没问题,但几个细节可能导致刷新令牌无法正确保存或验证:

  • 要确保刷新操作成功后才写入token.json,当前代码块虽包含写入逻辑,但未做异常隔离(若刷新失败仍会覆盖文件)
  • creds.valid的判断可能存在缓存延迟:即使令牌快过期,valid可能仍返回True,导致错过刷新时机。建议提前检测令牌有效期,比如提前5分钟主动刷新

修改后的代码建议:

import os
import datetime
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

SCOPES = ["https://www.googleapis.com/auth/drive"]
creds = None

# 加载已保存的凭证
if os.path.exists("token.json"):
    creds = Credentials.from_authorized_user_file("token.json", SCOPES)

# 检查凭证有效性,主动提前刷新
if not creds or not creds.valid:
    refresh_success = False
    # 有刷新令牌时尝试刷新
    if creds and creds.refresh_token:
        # 提前检测:令牌已过期/即将过期(提前300秒)
        if creds.expired or (creds.expiry - datetime.datetime.now(datetime.timezone.utc)).total_seconds() < 300:
            try:
                creds.refresh(Request())
                # 刷新成功后立即保存新凭证
                with open("token.json", "w") as token:
                    token.write(creds.to_json())
                refresh_success = True
            except Exception as e:
                print(f"刷新失败: {e},将启动重新授权")
    
    # 刷新失败或无有效凭证时,启动授权流程
    if not refresh_success:
        flow = InstalledAppFlow.from_client_secrets_file(
            "client_secrets.json", SCOPES
        )
        creds = flow.run_local_server(port=0)
        with open("token.json", "w") as token:
            token.write(creds.to_json())

3. 系统时间不同步

OAuth2协议对时间同步要求严格,如果本地系统时间与Google服务器时间偏差超过5分钟,会直接导致令牌验证失败,触发invalid_grant错误。

解决:

  • 开启系统自动同步时间功能,确保本地时间与标准时间一致

4. 客户端配置错误

如果client_secrets.json对应的是Web应用而非桌面应用类型,刷新令牌可能无法正常生成或使用。

解决:

  • 登录Google Cloud控制台,确认OAuth客户端ID的类型为「桌面应用」,重新下载正确的client_secrets.json替换现有文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:22:48