Nginx+React+Django跨域配置求助:Cookie与CSRFToken异常
解决方案
一、调整Nginx配置(消除跨域根源)
将前端Nginx配置新增/api路径代理,让React的API请求直接走同域路径,避免跨域问题,同时内部请求仍指向localhost后端:
// REACT APP server { listen 80; listen [::]:80; root /link-to/build; index index.html; server_name pinode; # 新增:代理API请求到Django后端 location /api/ { proxy_pass http://localhost:8000/api/; include proxy_params; # 确保Cookie和请求头正确传递 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cookie_path / "/; HttpOnly; SameSite=Lax"; } location / { try_files $uri /index.html; } }
Django后端的Nginx配置可限制仅本地监听,避免外部直接访问:
// Django APP/Gunicorn server { listen localhost:8000; # 仅允许本地访问后端 server_name localhost; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /link-to/myproject; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
二、Django settings.py 配置
- 先安装依赖:
pip install django-cors-headers
- 修改settings.py核心配置:
INSTALLED_APPS = [ # ... 原有应用 'corsheaders', ] MIDDLEWARE = [ # 必须放在CommonMiddleware之前 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... 原有中间件 ] # 允许前端域名跨域访问(代理模式下可保留,兼容开发场景) CORS_ALLOWED_ORIGINS = [ "http://pinode", "http://localhost:3000", ] CORS_ALLOW_CREDENTIALS = True # CSRF信任源,匹配前端访问域名 CSRF_TRUSTED_ORIGINS = [ "http://pinode", "http://localhost:3000", ] # Cookie安全配置 SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_HTTPONLY = False # 允许前端读取CSRF Token CSRF_COOKIE_SAMESITE = 'Lax' # 适配Nginx代理的头信息 USE_X_FORWARDED_HOST = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'http') # 若用HTTPS则改为https
三、Axios 配置修改
调整API请求路径为同域的/api/*,并确保携带Cookie和CSRF Token:
import axios from 'axios'; const api = axios.create({ baseURL: '/api/', withCredentials: true, // 强制携带Cookie }); // 自动从Cookie中读取CSRF Token并添加到请求头 api.interceptors.request.use((config) => { const csrfToken = document.cookie.match(/csrftoken=([^;]+)/)?.[1]; if (csrfToken) { config.headers['X-CSRFToken'] = csrfToken; } return config; }); export default api;
之后React中的API调用改为:
// 示例登录请求 api.post('/login/', { username, password }) .then(res => { /* 处理响应 */ }) .catch(err => { /* 处理错误 */ });
问题对应解决说明
- Set-Cookie跨域失败:通过Nginx代理实现同域请求,Cookie可正常写入;若保留跨域模式,需确保Django开启
CORS_ALLOW_CREDENTIALS并配置Cookie的SameSite=Lax属性。 - CORS策略拒绝:代理后同域无CORS问题,跨域模式下需在
CORS_ALLOWED_ORIGINS中添加前端访问域名。 - 缺少csrftoken:Axios开启
withCredentials后可正确读取Cookie中的CSRF Token,同时Django的CSRF_TRUSTED_ORIGINS需包含前端域名,确保CSRF验证通过。
内容的提问来源于stack exchange,提问作者Ahmed A
相关产品推荐
相关产品推荐

