You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:58:13