如何在OAuth 2.0中使用refresh token自动获取access token
问题原因及解决方法
一、首次人工授权的问题
OAuth 2.0 桌面应用授权流的设计要求首次必须由账号持有人人工确认授权,无法完全跳过这一步。你只需要在本地桌面环境完成一次授权,拿到包含有效refresh_token的token.json文件后,将该文件部署到服务端,后续所有运行都不需要再人工操作。
二、令牌无法自动刷新的常见原因及修复
你当前的代码逻辑本身符合谷歌官方API的刷新规范,刷新失效通常是以下几个原因导致:
- 你的谷歌云OAuth客户端处于测试发布状态:测试模式下生成的refresh_token默认有效期只有7天,到期后会自动作废,你需要进入谷歌云控制台的「API和服务」-「OAuth同意屏幕」页面,将应用发布状态从「测试」改为「正式发布」,刷新token就会长期有效。
- 授权范围格式错误:你原代码中SCOPES赋值为字符串,谷歌官方要求授权范围必须传入列表格式,这也是可能导致刷新失败的隐藏问题。
- 依赖包缺失或导入错误:请确认你已经完整导入以下依赖:
import os import json from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow
三、优化后的自动刷新代码
你可以直接使用以下简化后的代码,不需要手动读取token.json获取access token,creds对象刷新后会自动更新token属性,运行更稳定:
# 授权范围调整为官方要求的列表格式 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: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: # 仅首次无token.json时才会触发浏览器授权 flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 刷新/首次授权后更新保存的凭证 with open('token.json', 'w') as token: token.write(creds.to_json()) # 直接从creds对象拿最新的access token,不需要二次读文件 access_token = creds.token
内容的提问来源于stack exchange,提问作者Mulon
相关产品推荐
相关产品推荐

