普通网友 2025-07-09 17:15 采纳率: 97.8%
浏览 5
已采纳

问题:Django Admin跨域请求为何会触发Origin Checking Failed错误?

在使用 Django Admin 时,开发者可能会遇到跨域请求(CORS)触发 **Origin Checking Failed** 错误的问题。此错误通常由 Django 的 CSRF 保护机制引起,即使已配置 CORS 相关中间件(如 `django-cors-headers`),某些场景下仍会阻止来自非同源的请求。 核心原因在于:Django Admin 默认要求所有 POST 请求携带合法的 CSRF Token,并验证请求头中的 `Origin` 或 `Referer` 字段是否可信。而在跨域请求中,若前端未正确携带认证信息或未配置 `CSRF_TRUSTED_ORIGINS`,则会导致校验失败。 解决方法包括:合理配置 `CORS_ALLOWED_ORIGINS`、启用并正确设置 `CSRF_TRUSTED_ORIGINS`,以及确保跨域请求携带 Cookie 和 CSRF Token。
  • 写回答

1条回答 默认 最新

  • 希芙Sif 2025-07-09 17:16
    关注

    1. Django Admin 中跨域请求触发 Origin Checking Failed 的问题概述

    在使用 Django Admin 界面进行前后端分离开发时,开发者常常会遇到跨域请求被拦截的问题。尤其是在通过前端框架(如 Vue、React)向 Django 后端发起 POST 请求时,即便已经引入了 django-cors-headers 插件并配置了相关参数,依然可能遇到如下错误:

    [INFO] Forbidden (Origin checking failed - http://localhost:3000 does not match any trusted origins.): /admin/login/

    该错误的核心原因在于 Django 内置的 CSRF 保护机制。Django 默认对所有表单提交(尤其是 POST 请求)要求携带合法的 CSRF Token,并验证请求头中的 OriginReferer 是否在白名单中。

    2. 跨域请求失败的常见场景与分析过程

    • 前端运行在 http://localhost:3000,后端运行在 http://localhost:8000,但未正确配置信任源
    • 使用 fetchAxios 发起请求时未设置 withCredentials: true,导致 Cookie 无法携带
    • CSRF Token 未正确附加到请求头中
    • Django 设置中 CSRF_TRUSTED_ORIGINS 缺失或格式不正确

    下图展示了典型的跨域请求流程以及 CSRF 校验的关键节点:

                graph TD
                    A[Frontend App] -->|POST /admin/login/| B(Django Server)
                    B --> C{Is Origin Trusted?}
                    C -- Yes --> D{CSRF Token Valid?}
                    D -- Yes --> E[Login Success]
                    D -- No --> F[Forbidden: CSRF Failed]
                    C -- No --> G[Forbidden: Origin Checking Failed]
            

    3. 解决方案详解

    以下为解决该问题的详细步骤和配置说明:

    1. 安装并启用 django-cors-headers:
      安装插件以支持跨域请求:
      pip install django-cors-headers
      settings.py 中添加中间件和配置:
      MIDDLEWARE = [
          ...
          'corsheaders.middleware.CorsMiddleware',
          'django.middleware.common.CommonMiddleware',
          ...
      ]
      CORS_ALLOWED_ORIGINS = [
          "http://localhost:3000",
      ]
    2. 配置 CSRF_TRUSTED_ORIGINS:
      添加信任的来源列表以绕过 Origin 检查:
      CSRF_TRUSTED_ORIGINS = [
          "http://localhost:3000",
      ]
      注意:此配置需包含协议(http/https)和域名,不能带路径。
    3. 确保请求携带 Cookie 和 CSRF Token:
      前端代码示例(使用 fetch):
      fetch("http://localhost:8000/admin/login/", {
          method: "POST",
          credentials: "include",
          headers: {
              "X-CSRFToken": getCookie("csrftoken"),
              "Content-Type": "application/json"
          },
          body: JSON.stringify({ username, password })
      });
      其中 getCookie() 函数用于从浏览器 cookie 中获取 csrftoken。
    4. 启用 Session 认证和 CSRF 验证中间件:
      确保 Django 的认证中间件已启用:
      MIDDLEWARE += [
          'django.contrib.auth.middleware.AuthenticationMiddleware',
          'django.middleware.csrf.CsrfViewMiddleware',
      ]

    4. 关键配置项对比表格

    配置项作用是否必须示例值
    CORS_ALLOWED_ORIGINS允许跨域请求的源地址["http://localhost:3000"]
    CSRF_TRUSTED_ORIGINSCSRF 校验时信任的源地址["http://localhost:3000"]
    CORS_ALLOW_CREDENTIALS是否允许携带 Cookie视情况True

    5. 进阶建议与调试技巧

    • 使用浏览器开发者工具查看 Network 面板,确认请求头中是否包含 X-CSRFTokenCookie
    • 检查服务器日志输出,定位具体的拒绝信息(如 “Origin checking failed”)
    • 测试阶段可临时关闭 CSRF 验证(仅限本地环境):
      @csrf_exempt
      但生产环境切勿使用。
    • 对于部署在 HTTPS 上的项目,确保 CSRF_TRUSTED_ORIGINS 使用 https 协议
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 7月9日