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

使用Django+React对接Google Auth时遇redirect_uri_mismatch错误求助

解决Django对接Google OAuth的redirect_uri_mismatch错误

核心问题:重定向URI不匹配

Error 400: redirect_uri_mismatch 本质是代码中设置的REDIRECT_URI和Google Cloud控制台里配置的重定向URI不完全一致,Google OAuth要求两者必须精确匹配——包括协议(http/https)、域名、端口、路径,甚至末尾的斜杠都不能有差异。

排查步骤:

  • 对比代码中的REDIRECT_URI(http://localhost:3000/parent/our_information)和控制台配置的URL,重点检查:
    • 协议:控制台是否写的是http(本地开发无需用https)
    • 端口:是否为3000而非其他端口
    • 路径:/parent/our_information是否完全一致,有无多写/少写斜杠、大小写错误
    • 确认控制台修改后已保存,部分场景下配置生效需等待1-2分钟

代码优化建议(针对Django新手)

1. 配置项统一移到settings.py

把硬编码的配置放到项目settings.py中,方便后续维护:

# settings.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

GOOGLE_CLIENT_SECRET_FILE = os.path.join(BASE_DIR, 'your_app_name/client_secret.json')
GOOGLE_SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
GOOGLE_REDIRECT_URI = 'http://localhost:3000/parent/our_information'

视图中导入使用:

from django.conf import settings

# 替换原硬编码常量
CLIENT_SECRET_FILE = settings.GOOGLE_CLIENT_SECRET_FILE
SCOPES = settings.GOOGLE_SCOPES
REDIRECT_URI = settings.GOOGLE_REDIRECT_URI

2. 将ExchangeCodeView改为POST请求

用GET传递授权码code存在安全风险,改为POST更符合OAuth最佳实践:

from rest_framework import status
from rest_framework.response import Response

class ExchangeCodeView(APIView):
    def post(self, request):
        code = request.data.get('code')
        if not code:
            return Response({'error': '授权码code不能为空'}, status=status.HTTP_400_BAD_REQUEST)
        
        flow = Flow.from_client_secrets_file(
            CLIENT_SECRET_FILE,
            scopes=SCOPES,
            redirect_uri=REDIRECT_URI
        )
        
        try:
            flow.fetch_token(code=code)
        except Exception as e:
            return Response({'error': f'兑换授权码失败:{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
        
        credentials = flow.credentials
        return Response({
            'access_token': credentials.token,
            'refresh_token': credentials.refresh_token
        })

前端对应修改:

const handleCallback = () => {
  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');
  axios.post('http://localhost:8000/email/exchangeToken/', { code })
    .then((response) => {
      const { access_token, refresh_token } = response.data;
      console.log('Access Token:', access_token);
      console.log('Refresh Token:', refresh_token);
    })
    .catch((error) => {
      console.error(error);
    });
};

3. 配置CORS解决跨域问题

前端(3000端口)和Django(8000端口)属于不同域,需配置跨域允许:

  1. 安装依赖:pip install django-cors-headers
  2. 在settings.py中添加配置:
INSTALLED_APPS = [
    # ...其他已安装应用
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 需放在CommonMiddleware之前
    'django.middleware.common.CommonMiddleware',
    # ...其他中间件
]

# 允许本地前端访问
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]

4. 确保获取refresh_token

默认情况下Google不会返回refresh_token,需在生成授权URL时添加access_type='offline'参数:

auth_url, _ = flow.authorization_url(
    prompt='consent',
    access_type='offline'  # 强制返回refresh_token
)

额外注意事项

  • 确保Google Cloud中创建的是Web应用类型的OAuth客户端ID,而非桌面/移动端类型
  • 本地开发时不要混用localhost和127.0.0.1,代码和控制台配置保持一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:17:32