Django Rest + Vue.js Axios CSRF验证失败问题求助
解决DRF + Vue + Axios的CSRF Token缺失问题
1. 修正Django CSRF_TRUSTED_ORIGINS配置
你的CSRF_TRUSTED_ORIGINS存在格式错误,需调整为包含前端实际访问地址(带端口,若使用非80端口):
CSRF_TRUSTED_ORIGINS = [ "http://localhost", "http://127.0.0.1", # 若Nginx代理用了特定端口(如8080),补充: "http://localhost:8080", "http://127.0.0.1:8080" ]
注意:Django 3.2+版本使用复数形式CSRF_TRUSTED_ORIGINS,旧版本为单数,需匹配你的Django版本。
2. 配置Axios自动绑定CSRF Token
不要手动硬编码请求头,让Axios自动从Cookie读取Token:
// Vue项目全局Axios配置(如main.js) import axios from 'axios' axios.defaults.xsrfCookieName = 'csrftoken' axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN' // 必须开启,否则浏览器不会在代理场景下携带Cookie axios.defaults.withCredentials = true Vue.prototype.$axios = axios
3. 调整Nginx反向代理配置
确保Nginx正确传递请求头与Cookie,示例配置:
server { listen 80; server_name localhost; # 前端资源代理 location / { proxy_pass http://vue-container:8080; # 替换为你的Vue容器地址 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; # 配置Cookie跨域策略 proxy_cookie_path / "/; SameSite=Lax"; } # 后端API代理 location /api/ { proxy_pass http://django-container:8000/api/; # 替换为你的Django容器地址 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 / "/; SameSite=Lax"; } }
4. 补充Django Cookie安全配置
在settings.py中添加或调整:
# 允许前端JS读取CSRF Cookie CSRF_COOKIE_HTTPONLY = False # Session Cookie保持HttpOnly更安全 SESSION_COOKIE_HTTPONLY = True # 适配跨域Cookie策略 CSRF_COOKIE_SAMESITE = 'LAX' SESSION_COOKIE_SAMESITE = 'LAX' # 开发环境关闭Secure CSRF_COOKIE_SECURE = False SESSION_COOKIE_SECURE = False # 同域名下留空,让Django自动处理 CSRF_COOKIE_DOMAIN = None SESSION_COOKIE_DOMAIN = None
5. 确保前端先获取CSRF Cookie
发送POST/PUT/DELETE请求前,先发起一个GET请求(如访问后端健康检查接口/api/health/),确保浏览器已获取csrftoken Cookie。
6. 修复Swagger UI的CSRF问题
在DRF的Swagger配置中(如urls.py),添加CSRF支持:
from drf_yasg.views import get_schema_view from drf_yasg import openapi from rest_framework import permissions from django.views.decorators.csrf import csrf_exempt schema_view = get_schema_view( openapi.Info( title="API Docs", default_version='v1', ), public=True, permission_classes=[permissions.AllowAny], ) urlpatterns = [ # ... path('swagger/', csrf_exempt(schema_view.with_ui('swagger', cache_timeout=0)), name='schema-swagger-ui'), ]
内容的提问来源于stack exchange,提问作者Philipp Homberger
相关产品推荐
相关产品推荐

