Flask Web应用切换Google Calendar API Web客户端ID后重定向失败求助
问题分析与解决
核心问题
切换Google Calendar API的Client ID为Web应用版后,授权URL生成正常但无法自动重定向,手动访问URL可完成授权流程。应用部署在Render平台(要求HTTPS重定向URI)。
桌面版实现代码
def find_creds(): creds = None if current_user.token_json: credentials_dict = json.loads(current_user.token_json) creds = google.oauth2.credentials.Credentials(credentials_dict["token"], refresh_token=credentials_dict["refresh_token"], token_uri=credentials_dict["token_uri"], client_id=credentials_dict["client_id"], client_secret=credentials_dict["client_secret"], scopes=credentials_dict["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( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) current_user.token_json = creds.to_json() db.session.commit() return creds
Web应用版当前实现代码
def find_creds(): if not current_user.token_json: print("not creds") get_creds() else: credentials_dict = json.loads(current_user.token_json) creds = google.oauth2.credentials.Credentials( credentials_dict["token"], refresh_token=credentials_dict["refresh_token"], token_uri=credentials_dict["token_uri"], client_id=credentials_dict["client_id"], client_secret=credentials_dict["client_secret"], scopes=credentials_dict["scopes"]) return creds def get_creds(): print("got to get_creds") flow = Flow.from_client_secrets_file("creds2.json", scopes=SCOPES) flow.redirect_uri = url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url( access_type='offline', prompt='consent' ) print("made to redirect url") print(authorization_url) return redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): print("made to auth callback") flow = Flow.from_client_secrets_file("creds2.json", scopes=SCOPES) flow.redirect_uri = url_for('oauth2callback', _external=True) authorization_response = request.url flow.fetch_token(authorization_response=authorization_response) current_user.token_json = flow.credentials.to_authorized_user_info() db.session.commit() return redirect(url_for('home'))
问题定位
find_creds函数中,检测到无有效凭证时仅调用了get_creds(),但未返回该函数生成的重定向响应。Flask路由必须返回响应对象才能触发页面跳转,当前代码未传递响应,导致重定向失效。
修复方案
1. 修正find_creds的响应返回
修改函数,在需要授权时返回get_creds()的结果:
def find_creds(): if not current_user.token_json: print("not creds") return get_creds() # 添加return,传递重定向响应 else: credentials_dict = json.loads(current_user.token_json) creds = google.oauth2.credentials.Credentials( credentials_dict["token"], refresh_token=credentials_dict["refresh_token"], token_uri=credentials_dict["token_uri"], client_id=credentials_dict["client_id"], client_secret=credentials_dict["client_secret"], scopes=credentials_dict["scopes"]) return creds
2. 修复凭证存储格式
回调函数中flow.credentials.to_authorized_user_info()返回字典,需转为JSON字符串存储,否则后续加载会报错:
# 替换回调函数中的对应行 current_user.token_json = json.dumps(flow.credentials.to_authorized_user_info())
额外验证项
- 确认Google Cloud Console中Web应用的重定向URI已配置为Render部署后的HTTPS地址(如
https://your-app.onrender.com/oauth2callback),且与url_for('oauth2callback', _external=True)生成的地址完全一致。 - 检查
creds2.json中的Client ID和Client Secret为Web应用类型的凭证,而非桌面应用。
内容的提问来源于stack exchange,提问作者Michael Coleman
相关产品推荐
相关产品推荐

