使用Gmail API时遇到Token过期吊销及MismatchingStateError报错如何解决
问题根因与解决方案
1. 测试模式Refresh Token 7天过期问题
你现在的OAuth同意屏幕处于测试模式,这是Google的默认规则:测试模式下所有颁发的刷新Token最长有效期只有7天,到期就会自动失效,调整代码无法解决,核心要修改OAuth配置:
- 打开Google Cloud控制台对应项目的「API和服务」→「OAuth同意屏幕」页面
- 直接将应用状态从「测试」切换为「发布」即可,个人自用不需要提交官方验证,只要你只用自己的Gmail账号授权,刷新Token就会变为长期有效,不会再出现每周过期的问题。
2. MismatchingStateError报错问题
你用的InstalledAppFlow.run_local_server()是面向本地桌面应用的授权方法,逻辑是在当前运行代码的设备启动临时本地服务处理OAuth回调,你在云服务器上运行这段代码触发授权时,本地浏览器回调的状态参数和云服务器存的状态参数不匹配,就会触发这个CSRF校验报错。
解决方法非常简单:
- 先在你自己的本地电脑(Windows/Mac均可)运行你贴的这段授权代码,浏览器弹出授权页时用你要绑定的Gmail账号完成授权,本地会生成有效的
token.json文件 - 将本地生成的
token.json和credentials.json一起上传到Google Cloud服务器的项目对应目录下 - 服务器上的代码不需要修改,只要保证不删除
token.json,程序会自动用刷新Token续期Access Token,不需要再触发新的授权流程。
代码优化建议
你可以额外加判断逻辑,避免服务器运行时意外触发授权流程导致报错,参考修改如下:
creds = None if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', self.SCOPES) else: # 服务器环境下直接抛出错误,不要触发授权流程 raise Exception("未找到token.json,请先在本地完成授权后上传该文件") if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: raise Exception("Token已失效且无可用刷新Token,请重新在本地生成token.json后上传") with open('token.json', 'w') as token: token.write(creds.to_json()) service = build('gmail', 'v1', credentials=creds) try: # Do my stuff text = self.__get_new_msgs_text(service, 'me') return text except NotFindException: raise NotFindException()
内容的提问来源于stack exchange,提问作者Иван Светушков
相关产品推荐
相关产品推荐

