Django无CSRF Token实现CSRF及跨端协作下CSRF启用方案咨询
Hey folks, let's tackle these two Django CSRF questions one by one—they're common scenarios when working with frontend teams or exploring alternative protection methods:
CSRF tokens are the standard go-to, but there are alternative (though often supplementary) methods you can use:
- Validate request origin via Referer/Origin headers
Django's CSRF middleware already checks these headers by default, especially for HTTPS requests. You can configureCSRF_TRUSTED_ORIGINSin yoursettings.pyto list trusted domains—if a request's Referer or Origin matches one of these, it passes validation. Note that some clients might strip the Referer header, so this isn't 100% foolproof, but it's a solid layer of defense. - Leverage SameSite cookie attributes
Django sets the CSRF cookie withSameSite=Laxby default, which restricts the cookie to same-site requests (or safe cross-site GET requests). You can tighten this toSameSite=Strictinsettings.py(CSRF_COOKIE_SAMESITE = 'Strict') to block even more cross-site requests, though this might break legitimate flows like cross-site form submissions (e.g., a user clicking a link from another site that posts to your app). - IP-based validation (not recommended for public systems)
You could check if the request's IP is in a trusted list, but this is risky—IPs can be spoofed, and users might share IPs via proxies or corporate networks. Only use this for internal, closed systems where you have full control over client IPs.
If embedding the token in templates isn't an option, the key is to let the frontend fetch the token separately and include it in requests. Here's how:
Expose an API endpoint to return the CSRF token
Create a simple view that returns the current user's CSRF token. This lets the frontend call the endpoint on page load to grab the token:from django.http import JsonResponse from django.middleware.csrf import get_token def csrf_token_view(request): return JsonResponse({'csrf_token': get_token(request)})Then map this view to a URL (e.g.,
/api/csrf-token/), and have the frontend fetch this endpoint, store the token, and add it as theX-CSRFTokenheader in all POST/PUT/DELETE requests.Let the frontend read the CSRF token from cookies
Django automatically sets acsrftokencookie for authenticated users (and even for anonymous users ifCSRF_COOKIE_HTTPONLYisFalse, which is the default). The frontend can extract this cookie value and attach it to the request header. Here's a quick JS snippet to do that:function getCsrfToken() { let token = null; const cookies = document.cookie.split(';'); for (const cookie of cookies) { const [name, value] = cookie.trim().split('='); if (name === 'csrftoken') { token = decodeURIComponent(value); break; } } return token; } // Use in fetch/Axios: const csrfToken = getCsrfToken(); fetch('/your-endpoint/', { method: 'POST', headers: { 'X-CSRFToken': csrfToken, 'Content-Type': 'application/json' }, body: JSON.stringify(yourData) });Just make sure
CSRF_COOKIE_HTTPONLYstaysFalsein your settings—if it's set toTrue, frontend JS can't access the cookie, so you'll need to use the API endpoint method instead.Confirm frontend request requirements
Remind the frontend team that all state-modifying requests (POST, PUT, DELETE, etc.) must include theX-CSRFTokenheader with the valid token. Django's CSRF middleware will automatically validate this header against the stored cookie.
内容的提问来源于stack exchange,提问作者Guldam Kwak

