Python如何无需用户输入实现Gmail API自动认证与凭证刷新
解决方案
问题根源
你现有代码的自动刷新逻辑本身是成立的,无法长期自动运行的原因有三个:
- Google Cloud控制台中你的OAuth应用处于「测试」状态,该状态下颁发的refresh_token强制7天过期,过期直接作废,无法用于自动刷新凭证
- 首次授权调用时没有指定
access_type=offline参数,返回的凭证中不包含长期有效的refresh_token,过期后自然无法走自动刷新流程 - 代码中文件路径写法不统一,cron执行时工作目录和你手动跑脚本的目录不一致,会直接读不到已有的token.json,误触发需要浏览器的手动授权分支
操作步骤
1. 调整Google Cloud OAuth配置
- 进入对应项目的Google Cloud控制台,打开「API和服务」-「OAuth同意屏幕」页面
- 将应用发布状态从「测试」切换为「生产」,个人自用应用不需要提交审核,切换后颁发的refresh_token即为长期有效
- 确认OAuth同意屏幕的已授权作用域包含你脚本用到的所有Gmail API权限
- 进入「凭据」页,确认你使用的credentials.json对应「桌面应用」类型的OAuth 2.0客户端ID,不要使用Web应用等其他类型的凭据
2. 修改认证代码
修正路径问题,同时给首次授权流程加参数,强制返回长期refresh_token,修改后的完整认证函数如下:
import os from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow # 替换为你实际使用的Gmail API权限范围 SCOPES = ["https://www.googleapis.com/auth/gmail.send"] # 固定用脚本所在目录的绝对路径,避免cron执行时路径异常 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) def get_creds(): creds = None token_path = os.path.join(SCRIPT_DIR, "token.json") cred_path = os.path.join(SCRIPT_DIR, "credentials.json") if os.path.exists(token_path): creds = Credentials.from_authorized_user_file(token_path, SCOPES) 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(cred_path, SCOPES) # 关键参数:offline模式申请长期refresh_token,consent参数确保首次授权时一定返回refresh_token creds = flow.run_local_server(port=0, access_type="offline", prompt="consent") with open(token_path, "w") as token: token.write(creds.to_json()) return creds
3. 首次授权与部署
- 不要在无桌面环境的树莓派上跑首次授权流程。先在带浏览器的普通电脑上运行一次修改后的脚本,弹出授权页面时正常点击允许,脚本目录下会生成包含refresh_token字段的token.json
- 将生成的token.json和credentials.json一起上传到树莓派的脚本目录下
- 配置cron任务时统一使用绝对路径调用脚本,例如每日早8点执行的配置写法为
0 8 * * * /usr/bin/python3 /home/pi/your_script_dir/send_mail.py - 部署完成后可以手动测试一次,确认脚本无需弹出浏览器即可正常完成认证、发信流程,后续凭证过期会自动刷新,不需要人工干预
注意事项
- 只要token.json文件不丢失、你不在Google账号后台主动撤销该应用的授权,refresh_token就会一直有效,不需要重复手动授权
- 如果后续调整了SCOPES权限范围,需要重新执行一次首次授权流程,生成新的token.json替换树莓派上的旧文件
- 个人自用的生产状态OAuth应用不会产生额外费用,只要不开放给其他谷歌账号使用,不需要提交官方审核
内容的提问来源于stack exchange,提问作者Konstantin Konstantinov
相关产品推荐
相关产品推荐

