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

ReactJS与Django跨域下如何通过Axios正确传递CSRF Token?

Hey there! Let's tackle this CSRF issue you're facing while setting up user registration with React and a separate Django backend. Cross-domain CSRF handling is one of the most common pain points when working with fully decoupled stacks, but once you get the pieces aligned, it works smoothly. Here's a step-by-step breakdown to fix it:

1. Why You're Seeing This Error

Django's CSRF protection relies on matching a token stored in a cookie with a token sent in the request header. When your React app is on a different domain, even with withCredentials: true, a few critical pieces are missing:

  • Django might not trust your frontend's origin to send CSRF requests
  • Your frontend isn't properly fetching and attaching the CSRF token to the registration request
  • Cross-origin cookie rules might be blocking the CSRF cookie from being stored or sent
2. Backend (Django) Configuration

First, let's get Django set up to accept cross-origin requests and trust your frontend:

Install & Configure CORS Headers

Django doesn't handle CORS out of the box, so we'll use the django-cors-headers package:

  1. Install it:
    pip install django-cors-headers
    
  2. Update your settings.py:
    # Add corsheaders to INSTALLED_APPS
    INSTALLED_APPS = [
        # ... other existing apps
        'corsheaders',
    ]
    
    # Add CorsMiddleware BEFORE CommonMiddleware (order matters!)
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        # Keep CsrfViewMiddleware enabled - it's required for CSRF protection
        'django.middleware.csrf.CsrfViewMiddleware',
        # ... other middleware
    ]
    
    # Allow your React app's origin (replace with your actual frontend URL)
    CORS_ALLOWED_ORIGINS = [
        "http://localhost:3000",
    ]
    
    # Allow credentials (cookies) to be sent cross-domain
    CORS_ALLOW_CREDENTIALS = True
    
    # Trust your frontend's origin for CSRF (critical for Django 3.2+)
    CSRF_TRUSTED_ORIGINS = [
        "http://localhost:3000",
    ]
    
    # Optional: Skip for local dev - set only if using custom domains
    # SESSION_COOKIE_DOMAIN = ".yourdomain.com"
    # CSRF_COOKIE_DOMAIN = ".yourdomain.com"
    

(Optional) Add a Dedicated CSRF Token Endpoint

While you can fetch the CSRF cookie via any GET request to Django, creating a dedicated endpoint makes the process explicit. Add this to your views.py:

from django.http import JsonResponse
from django.middleware.csrf import get_token

def get_csrf_token(request):
    # This view sets the CSRF cookie and returns the token value
    return JsonResponse({'csrfToken': get_token(request)})

Then map it in urls.py:

from django.urls import path
from .views import get_csrf_token, register_user # Your existing registration view

urlpatterns = [
    path('api/get-csrf/', get_csrf_token, name='get_csrf'),
    path('api/register/', register_user, name='register'),
    # ... other URLs
]
3. Frontend (React + Axios) Setup

Now let's configure React to fetch the CSRF token and attach it to your registration request:

Global Axios Configuration

Set up Axios to automatically handle credentials and CSRF tokens:

import axios from 'axios';

// Configure Axios globally
axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://localhost:8000'; // Replace with your Django API URL

// Add an interceptor to automatically attach the CSRF token to requests
axios.interceptors.request.use((config) => {
    // Extract the CSRF token from browser cookies
    const csrfToken = document.cookie
        .split('; ')
        .find(row => row.startsWith('csrftoken='))
        ?.split('=')[1];
    
    if (csrfToken) {
        config.headers['X-CSRFToken'] = csrfToken;
    }
    return config;
}, (error) => {
    return Promise.reject(error);
});

Handle Registration Request

Make sure to fetch the CSRF token first (this ensures the cookie is set in the browser) before sending your registration data:

const handleRegister = async (formData) => {
    try {
        // First, fetch the CSRF token to set the cookie in the browser
        await axios.get('/api/get-csrf/');
        
        // Then send the registration request with your user data
        const response = await axios.post('/api/register/', formData);
        
        console.log('Registration successful!', response.data);
        // Handle success (e.g., redirect to login page)
    } catch (error) {
        console.error('Registration failed:', error.response?.data || error.message);
        // Handle error (e.g., display error message to the user)
    }
};
4. Common Pitfalls to Check
  • Browser Third-Party Cookie Blocking: Some browsers (like Chrome) block third-party cookies by default in non-incognito mode. For development, you can temporarily allow this in your browser settings.
  • Middleware Order: Ensure CorsMiddleware comes before CommonMiddleware in your Django settings—this is critical for CORS headers to be applied correctly.
  • DRF Session Authentication: If you're using Django Rest Framework's SessionAuthentication, make sure your registration view is protected by CSRF (it should be by default if CsrfViewMiddleware is enabled).

That should get your registration request working smoothly! Let me know if you hit any snags along the way.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:44:37