Django集成Google Drive API:OAuth流程中断致应用冻结的解决方案求助
解决Django集成Google Drive API时OAuth中断导致应用冻结的问题
问题根源
你当前用的InstalledAppFlow是Google为桌面/命令行应用设计的授权工具,它的run_local_server(port=0)会阻塞主线程,一直等本地浏览器的授权回调。但Django是多用户web服务,阻塞主线程会让整个应用没法处理其他请求,直接陷入冻结——这完全是工具使用场景错误导致的核心问题。
正确解决方案:改用Web应用OAuth2流程
Django作为web应用,必须用Google OAuth2的web授权流程:引导用户跳转到Google的授权页面,通过回调视图处理授权结果(包括用户中断、取消授权的情况),全程不阻塞主线程。
步骤1:实现授权请求视图
这个视图生成Google授权URL,引导用户跳转至授权页面:
from django.shortcuts import redirect from google_auth_oauthlib.flow import Flow from django.conf import settings def google_drive_auth(request): # 初始化Web版Flow,redirect_uri要和Google控制台配置的完整URL一致 flow = Flow.from_client_secrets_file( settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON, scopes=self.SCOPES, # 替换为你定义的权限范围 redirect_uri=request.build_absolute_uri("/google-drive/callback/") ) # 生成授权URL,开启offline模式以获取刷新令牌 authorization_url, state = flow.authorization_url( access_type="offline", include_granted_scopes="true" ) # 保存state到session,用于回调时验证CSRF request.session["oauth_state"] = state return redirect(authorization_url)
步骤2:实现授权回调视图
这个视图处理Google的回调请求,捕获用户中断授权的情况:
from django.http import HttpResponseBadRequest, HttpResponseServerError from django.shortcuts import redirect from google_auth_oauthlib.flow import Flow from django.conf import settings def google_drive_callback(request): # 验证state参数,防止CSRF攻击 saved_state = request.session.get("oauth_state") current_state = request.GET.get("state") if not saved_state or saved_state != current_state: return HttpResponseBadRequest("无效的请求参数") flow = Flow.from_client_secrets_file( settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON, scopes=self.SCOPES, # 替换为你定义的权限范围 redirect_uri=request.build_absolute_uri("/google-drive/callback/"), state=saved_state ) try: # 用授权码交换访问令牌 flow.fetch_token(code=request.GET.get("code")) except Exception as e: # 用户中断授权(关闭浏览器)或取消授权时,request.GET中没有code参数 if "code" not in request.GET: return HttpResponseBadRequest("授权流程已中断或被取消") return HttpResponseServerError(f"令牌获取失败:{str(e)}") # 保存凭证到session或数据库(示例存session) creds = flow.credentials request.session["google_drive_creds"] = { "token": creds.token, "refresh_token": creds.refresh_token, "token_uri": creds.token_uri, "client_id": creds.client_id, "client_secret": creds.client_secret, "scopes": creds.scopes } # 重定向到你的业务页面 return redirect("show_courses")
关键注意事项
- 在Google Cloud控制台的OAuth2客户端配置里,把回调URL(比如
https://你的域名/google-drive/callback/)添加到授权重定向URI列表,否则会报错。 - 彻底删掉
InstalledAppFlow和run_local_server,web应用绝对不能用桌面应用的授权工具。 - 凭证建议存在数据库而非本地文件,适配多用户场景。
内容的提问来源于stack exchange,提问作者sodmzs2
相关产品推荐
相关产品推荐

