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

React+Django跨域CSRF令牌生成及请求头配置问题求助

解决React + Django应用的CSRF与跨域问题

嘿,我来帮你梳理这两个头疼的问题,结合你生产环境React和Django同服务器部署的情况,咱们一步步解决:

一、搞定CSRF Cookie生成与Token获取的问题

Django自带完整的CSRF防护机制,完全不用你手动生成Cookie,按以下步骤配置就行:

  1. 确认CSRF中间件已启用
    先检查settings.py里的MIDDLEWARE列表,确保这一行存在(默认是启用的,除非你手动删了):

    'django.middleware.csrf.CsrfViewMiddleware',
    
  2. 让前端稳稳拿到CSRF Token
    分两种场景处理:

    • 生产环境(同服务器部署):React编译后的静态文件放在Django的static目录,通过Django模板加载。这种情况下,直接在Django的基础模板里把CSRF Token渲染成全局变量最靠谱:
      在你的base.html(或类似模板)里加这段代码:
      <script>
        window.csrftoken = '{{ csrf_token }}';
      </script>
      
      这样React代码里直接用window.csrftoken就好,完全不用从Cookie读,避免首次请求Token为null的问题。
    • 开发阶段(跨域调试):需要让Django把CSRF Cookie发送给前端的开发服务器。首先在settings.py里添加信任的前端域名:
      CSRF_TRUSTED_ORIGINS = ['http://localhost:3000']  # 替换成你的React开发服务器地址
      
      然后用universal-cookie读取Cookie里的Token:
      import Cookies from 'universal-cookie';
      const cookies = new Cookies();
      // Django默认的CSRF Cookie名是csrftoken
      window.csrftoken = cookies.get('csrftoken');
      
      注意:首次请求前,先让前端访问一个Django的页面(比如首页)或者发一个不带Token的GET请求,Django会自动种下CSRF Cookie,之后就能读到Token了。

二、解决跨域请求头的报错问题

你遇到的Request header field X-CSRFToken is not allowed...报错,主要是预请求(OPTIONS)的响应头配置有问题,按以下调整:

  1. 修正跨域响应头配置
    别用*作为Access-Control-Allow-Origin!当请求带Cookie(CSRF Cookie属于Cookie)时,浏览器不允许用通配符,必须指定具体的前端域名,同时要加上Access-Control-Allow-Credentials: true:

    response = HttpResponse(json.dumps(software_settings), content_type="application/json")
    # 开发环境填React服务器地址,生产环境因为同域名,直接写当前域名或者去掉这个头
    response['Access-Control-Allow-Origin'] = "http://localhost:3000"
    response['Access-Control-Allow-Headers'] = "X-Requested-With, X-Prototype-Version, X-CSRF-Token"
    response['Access-Control-Allow-Methods'] = "POST, GET, OPTIONS"
    response['Access-Control-Allow-Credentials'] = "true"
    

    另外,Django的CsrfViewMiddleware会自动处理OPTIONS预请求,但如果是自定义视图,记得确保OPTIONS请求能返回200状态码。

  2. 生产环境可以完全去掉跨域配置
    因为生产环境React和Django部署在同一Apache服务器,属于同域名,根本不会有跨域问题,所以生产环境的视图里可以删掉所有Access-Control-*相关的响应头,避免多余配置。

额外的小优化建议

  • 把CSRF Token的获取逻辑封装成工具函数,兼顾两种场景:
    import Cookies from 'universal-cookie';
    function getCsrfToken() {
      // 优先用模板渲染的全局变量,没有的话从Cookie读
      return window.csrftoken || new Cookies().get('csrftoken');
    }
    
  • 如果用Axios发起请求,可以全局配置CSRF Token,不用每次写beforeSend:
    import axios from 'axios';
    axios.defaults.xsrfHeaderName = 'X-CSRFToken';
    axios.defaults.xsrfCookieName = 'csrftoken';
    
    这样Axios会自动从Cookie取Token并添加到请求头,省掉不少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:57:06