如何使用Python与Google Drive API避免Google API令牌过期失效?
问题根因
- 凭证校验逻辑不全:现有代码仅判断了凭证不存在或无效的场景,没有覆盖凭证过期的情况,过期的凭证不会触发
credentials.invalid为真,因此不会走重新授权/刷新流程,直接请求接口就会返回invalid_grant报错 - 依赖库已弃用:你使用的
oauth2client是谷歌官方已停止维护的库,对refresh token的自动刷新逻辑支持不完善 - OAuth应用处于测试状态:谷歌云平台默认对测试状态的OAuth应用发放的refresh token有效期仅为7天,到期自动撤销,这是平台强制规则
- 其他可能触发token撤销的原因:手动在谷歌账户中移除了该应用的访问权限、客户端密钥文件发生变更、授权scope调整、超过6个月未使用该凭证
修复步骤
1. 补全凭证校验逻辑
修改代码增加过期判断和自动刷新逻辑,不需要每次过期都跳浏览器手动授权,修改后的完整代码如下:
from googleapiclient.discovery import build from oauth2client import client, tools from oauth2client.file import Storage import httplib2 api_client_secret = r"C:\...\client_secret_0123456789-abc123def456ghi789.apps.googleusercontent.com.json" credential_file_path = r"C:\...\credential_sample.json" class GoogleDriveAccess: def __init__(self): self.service = self.get_authenticated_service(api_client_secret, credential_file_path, 'drive', 'v3', ['https://www.googleapis.com/auth/drive']) def get_authenticated_service(self, client_secret_file_path, credential_file_path, api_name, api_version, scopes): store = Storage(credential_file_path) credentials = store.get() if not credentials or credentials.invalid: flow = client.flow_from_clientsecrets(client_secret_file_path, scopes) credentials = tools.run_flow(flow, store) store.put(credentials) # 新增过期自动刷新逻辑 elif credentials.access_token_expired: credentials.refresh(httplib2.Http()) store.put(credentials) return build(api_name, api_version, credentials=credentials) if __name__ == '__main__': GoogleDriveAccess()
修改后先删除本地旧的credential_sample.json文件,运行一次完成手动授权,后续过期会自动刷新。
2. 解决refresh token7天自动过期问题
进入谷歌云控制台的OAuth同意屏幕配置页,将应用发布状态从「测试」修改为「正式发布」,个人自用不需要提交审核,修改完成后生成的refresh token就不会被谷歌自动7天回收。
3. 长期保持权限有效的注意事项
- 不要随意修改客户端密钥文件、调整申请的授权scope,如有变动需要删除旧的凭证文件重新授权
- 不要在谷歌账户的第三方访问权限管理中移除该应用
- 至少每6个月运行一次程序,避免凭证因长期未使用被谷歌自动回收
- 不要在多个设备频繁使用同一个refresh token,避免触发风控被撤销
内容的提问来源于stack exchange,提问作者lazarea
相关产品推荐
相关产品推荐

