Python调用Google Drive API上传文件凭证过期解决方案
Python对接Google Drive API长期有效凭证配置方案
默认流程生成的Access Token有效期仅1小时,过期后接口会直接返回401未授权,通过配置离线授权获取Refresh Token即可实现凭证自动续期,不需要手动重复授权。
前置依赖安装
先安装官方SDK包:pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
第一步:获取Refresh Token
Refresh Token不会默认返回,必须在首次授权时指定特殊参数才能拿到:
- 进入Google Cloud控制台对应项目的「API和服务」-「OAuth 2.0客户端ID」页面,确认当前使用的OAuth客户端类型为桌面应用,个人脚本使用该类型无需域名校验,配置成本最低
- 从控制台下载对应客户端的密钥文件,保存为本地的
credentials.json - 运行以下首次授权脚本,注意必须传入
access_type='offline'和prompt='consent'两个参数:前者要求授权服务器返回可用于离线刷新的Refresh Token,后者强制弹出授权确认页,避免因历史授权缓存导致不返回Refresh Token的问题
from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build # 仅需要文件上传权限就用该scope,遵循最小权限原则 SCOPES = ['https://www.googleapis.com/auth/drive.file'] flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES ) creds = flow.run_local_server( port=0, access_type='offline', prompt='consent' ) # 控制台输出的字符串就是Refresh Token,仅会在首次离线授权时返回一次,请妥善保存 print("Refresh Token:", creds.refresh_token) # 验证接口可用性 service = build('drive', 'v3', credentials=creds)
- 脚本运行后会自动打开浏览器授权页面,登录你的Google账号完成授权即可,不要切错账号。
第二步:业务脚本中使用Refresh Token实现自动续期
Google官方Auth SDK会自动在Access Token过期时用Refresh Token换取新的有效Token,不需要手动编写刷新逻辑,直接在初始化凭证时传入Refresh Token和对应客户端参数即可:
from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload SCOPES = ['https://www.googleapis.com/auth/drive.file'] # 替换为你自己的参数,client_id、client_secret可从之前下载的credentials.json中获取 creds = Credentials( token=None, refresh_token="替换为你第一步拿到的Refresh Token", token_uri="https://oauth2.googleapis.com/token", client_id="替换为你的OAuth客户端ID", client_secret="替换为你的OAuth客户端密钥", scopes=SCOPES ) # 初始化Drive服务 service = build('drive', 'v3', credentials=creds) # 文件上传示例 def upload_file(local_file_path, target_drive_folder_id=None): file_meta = {'name': local_file_path.split('/')[-1]} if target_drive_folder_id: file_meta['parents'] = [target_drive_folder_id] media = MediaFileUpload(local_file_path, resumable=True) resp = service.files().create( body=file_meta, media_body=media, fields='id' ).execute() print(f"上传完成,文件ID:{resp.get('id')}") return resp.get('id') # 调用测试 upload_file("./test.pdf")
注意事项
- Refresh Token并非永久有效:如果手动撤销了应用授权、或者该Token连续6个月未被使用,Google会自动将其作废,遇到失效情况重新走第一步的授权流程获取新Token即可
- 不要将Refresh Token、Client Secret等敏感信息硬编码到代码仓库中,建议存放在本地环境变量或权限受限的配置文件中
- 如果之前运行过授权脚本但没加
access_type='offline'参数,返回的凭证里不会包含Refresh Token字段,必须加上参数重新走一次授权流程才能拿到
内容的提问来源于stack exchange,提问作者Shubhanker Tiwari
相关产品推荐
相关产品推荐

