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

使用OAuth2.0授权后Google Calendar API v3报错求助

Django集成Google Calendar API授权失败的解决办法

问题根源

  1. 用错了工具类:InstalledAppFlow是给桌面应用设计的,Django作为Web应用,得用google_auth_oauthlib.flow.Flow才行
  2. 手动拼接redirect_uri的方式错误,应该在初始化Flow时直接指定,且必须和Google Cloud控制台里的配置完全一致
  3. 端口号出现笔误:代码里写的是43759,但实际跳转的是47759,导致地址无法访问
  4. 缺少回调视图:Google授权完成后需要跳回你的Django应用,必须有对应的路由和视图处理这个回调请求

一步步修复

1. 替换为Web专用的Flow生成授权URL

废弃InstalledAppFlow,改用Web应用适配的Flow类,正确指定重定向URI:

from google_auth_oauthlib.flow import Flow
from django.conf import settings

SCOPES = ['https://www.googleapis.com/auth/calendar']

def get_google_auth_url(request):
    # 从settings读取配置,避免硬编码路径
    flow = Flow.from_client_secrets_file(
        settings.GOOGLE_CLIENT_SECRET_PATH,
        scopes=SCOPES,
        # 直接指定重定向URI,比如开发环境的回调地址
        redirect_uri=settings.GOOGLE_REDIRECT_URI
    )
    # 加access_type='offline'才能获取刷新令牌,避免令牌过期后重复授权
    auth_url, state = flow.authorization_url(
        access_type='offline',
        include_granted_scopes='true'
    )
    # 把state存入session,回调时验证防止恶意请求
    request.session['oauth_state'] = state
    return auth_url

2. 同步Google Cloud控制台的重定向URI

  • 登录Google Cloud控制台,进入你的项目 → 「API和服务」→「凭据」
  • 找到你的OAuth 2.0客户端ID,编辑其重定向URI,确保和Django中GOOGLE_REDIRECT_URI完全一致,比如http://localhost:43759/calendar/oauth-callback/
  • 重点:端口号必须和Django实际运行的端口一致,修正43759/47759的笔误

3. 编写Django回调视图和路由

回调视图(示例存于app的views.py):

from google_auth_oauthlib.flow import Flow
from django.conf import settings
from django.http import HttpResponseRedirect
from django.shortcuts import render

def google_oauth_callback(request):
    # 验证state,防止CSRF攻击
    session_state = request.session.get('oauth_state')
    request_state = request.GET.get('state')
    if not session_state or session_state != request_state:
        return render(request, 'error.html', {'msg': '授权状态验证失败'})
    
    # 初始化Flow,复用之前存储的state和指定的重定向URI
    flow = Flow.from_client_secrets_file(
        settings.GOOGLE_CLIENT_SECRET_PATH,
        scopes=SCOPES,
        state=session_state,
        redirect_uri=settings.GOOGLE_REDIRECT_URI
    )
    # 用授权码交换访问令牌与刷新令牌
    flow.fetch_token(authorization_response=request.build_absolute_uri())
    
    # 拿到API调用凭证,可存入session或数据库供后续使用
    credentials = flow.credentials
    request.session['google_calendar_credentials'] = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret,
        'scopes': credentials.scopes
    }
    
    # 授权成功后跳转至业务页面
    return HttpResponseRedirect('/calendar/dashboard/')

路由配置(app的urls.py):

from django.urls import path
from . import views

urlpatterns = [
    # 生成授权URL的接口,前端可请求此接口获取auth_url
    path('calendar/get-auth-url/', views.get_google_auth_url, name='get_google_auth'),
    # 回调地址,必须与Google Cloud配置的重定向URI完全匹配
    path('calendar/oauth-callback/', views.google_oauth_callback, name='google_oauth_callback'),
]

4. 统一端口号

检查Django启动端口,确保GOOGLE_REDIRECT_URI、Google Cloud控制台配置的重定向URI、Django实际运行端口三者完全一致,彻底解决端口笔误问题。

额外提醒

  • 开发环境下,Django的ALLOWED_HOSTS需添加localhost和127.0.0.1,避免跨域或访问报错
  • 客户端密钥文件不要提交到代码仓库,建议通过环境变量或settings.py配置读取
  • 必须保留access_type='offline'参数,否则令牌过期后用户需要重新授权,影响使用体验

内容的提问来源于stack exchange,提问作者Germano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:25:10