如何让Flask跳转至Google OAuth页面后保持代码持续运行?
问题核心分析
你遇到的本质问题是:Flask的return redirect()会直接终止当前请求的处理流程。当你在submit函数中执行return redirect(url)时,浏览器会收到跳转指令并发起新请求到Google OAuth页面,原submit请求会立即结束,后续的数据库插入代码完全没有执行机会——这是HTTP「请求-响应」模型的特性,一个请求对应一个最终响应,redirect就是当前请求的终点。
解决方案
要实现「收集用户数据 → 跳转OAuth授权 → 授权完成后处理数据」的完整流程,需要将过程拆分为两个独立请求:
- 第一个请求:接收用户表单数据并暂存,再跳转至Google OAuth授权页
- 第二个请求:处理Google OAuth的回调,获取授权凭证后,取出暂存数据完成数据库插入
具体实现步骤
1. 配置Flask Session(用于暂存用户数据)
Flask的Session可以临时存储用户数据,需先设置一个安全的SECRET_KEY(生产环境请用随机生成的字符串)。
2. 修改submit函数:暂存数据后跳转OAuth
不再在submit中处理OAuth流程,先把用户提交的calendar和notify-code存入Session,再直接跳转到Google OAuth授权URL。
3. 新增OAuth回调路由
Google授权完成后会跳转到你预先配置的回调地址,在这个路由里完成凭证获取、数据取出和数据库插入操作。
修改后的后端代码示例
from flask import Flask, render_template, request, redirect, session from sql import db_settings, insert_command, google_json app = Flask(__name__) # 配置Session密钥,生产环境请从环境变量读取安全随机字符串 app.secret_key = 'your-secure-secret-key-here' @app.route("/page") def form(): return render_template('page.html') @app.route("/submit", methods=['POST']) def submit(): try: # 获取用户表单数据 calendar = request.values['calendar'] notify_code = request.values['notify-code'] # 暂存数据到Session session['calendar'] = calendar session['notify_code'] = notify_code # 获取Google OAuth授权URL及flow对象 _, auth_url, _, flow = google_json() # 暂存flow的state用于回调校验 session['flow_state'] = flow.state # 跳转到Google授权页 return redirect(auth_url) except Exception as e: print(e) # 调试用,生产环境替换为日志记录 return render_template('error.html') # 新增Google OAuth回调路由,需与Google Cloud控制台配置的重定向URI一致 @app.route("/google/callback") def google_callback(): try: # 取出Session中的暂存数据 calendar = session.get('calendar') notify_code = session.get('notify_code') flow_state = session.get('flow_state') if not calendar or not notify_code: return render_template('error.html', message='用户数据丢失') # 初始化flow并恢复之前的state wsgi_app, _, local_server, flow = google_json() flow.state = flow_state # 处理授权回调,获取凭证 local_server.handle_request() creds = flow.run_wait(wsgi_app) google_file = creds.to_json() # 执行数据库插入操作 insert_command(db_settings, calendar, notify_code, google_file) # 清理Session中的临时数据 session.pop('calendar', None) session.pop('notify_code', None) session.pop('flow_state', None) # 跳转到成功页面 return render_template('success.html') except Exception as e: print(e) return render_template('error.html') if __name__ == '__main__': app.debug = True app.run()
额外注意事项
- Google Cloud配置:必须在Google Cloud控制台的OAuth 2.0客户端ID设置中,将
http://localhost:5000/google/callback(或你的生产环境地址)添加到「已授权的重定向URI」列表,否则回调会失败。 - Session安全性:生产环境禁止硬编码
SECRET_KEY,建议通过环境变量读取,比如app.secret_key = os.environ.get('FLASK_SECRET_KEY')。 - 前端清理:你的前端JS中
clear函数调用的google.script.run.postMessage属于Google Apps Script代码,与当前Flask后端无关,建议删除以避免不必要的错误。
内容的提问来源于stack exchange,提问作者AndyLinOuO
相关产品推荐
相关产品推荐

