Django+Vue会话认证下POST请求CSRF缺失错误排查求助
问题描述
我有一个使用标准视图的Django网站,用于注册和登录。登录后可进入调用Django Rest Framework(DRF)后端接口的Vue应用,采用会话认证方式。从昨天起,所有POST、PUT、DELETE请求均返回403错误,提示“CSRF Failed: CSRF token missing”,但查看请求头发现登录时获取的csrftoken cookie已存在。我原本认为Vue的axios会自动携带该cookie请求后端,为何无法正常工作?
Vue配置(main.js)
import { createApp } from "vue"; import { createPinia } from "pinia"; import App from "./App.vue"; import router from "./router"; import axios from "axios"; import "./registerServiceWorker"; axios.defaults.baseURL = "http://localhost:8000"; axios.defaults.xsrfHeaderName = "X-CSRFToken"; axios.defaults.xsrfCookieName = "csrftoken"; axios.defaults.withCredentials = true; const pinia = createPinia(); const app = createApp(App); app.use(router); app.use(pinia); app.mount("#app");
Django配置
CORS_ALLOWED_ORIGINS = [ "http://localhost:8080", "http://localhost:8000", "http://127.0.0.1:8080", "http://127.0.0.1:8000", "http://localhost:file", "http://192.168.1.40:8080", ] CORS_ALLOW_CREDENTIALS = True SESSION_COOKIE_SAMESITE = None CSRF_TRUSTED_ORIGINS = [ "http://localhost:8080", "http://*.127.0.0.1", "http://127.0.0.1:8080", "http://192.168.1.40:8080", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "corsheaders.middleware.CorsMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ], "DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",), "DEFAULT_PARSER_CLASSES": [ "rest_framework.parsers.MultiPartParser", "rest_framework.parsers.JSONParser", ], "DEFAULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"], }
示例视图与请求代码
DRF视图
class LogoutView(APIView): def post(self, request): if request.user.is_authenticated: logout(request) return Response({"message": "Logged out successfully"}, status=status.HTTP_200_OK) else: return Response({"message": "No user is authenticated"}, status=status.HTTP_400_BAD_REQUEST)
Vue请求代码
async function logOut() { try { const response = await axios.post("/api/v1/users/logout/"); store.loggedIn = false; store.userID = 0; localStorage.removeItem("account"); window.location.href = "http://localhost:8000"; } catch (error) { console.log(error); } }
请求头信息
Accept application/json, text/plain, */* Accept-Encoding gzip, deflate, br Accept-Language en-US,en;q=0.5 Cache-Control no-cache Connection keep-alive Content-Length 0 Cookie csrftoken=C4T69wWvlRZ8HeLx80bAFBrHMoRJAUsT; sessionid=lu80tjrcqwqgs14i4qgowob37ejbk90k Host localhost:8000 Origin http://localhost:8080 Pragma no-cache Referer http://localhost:8080/ Sec-Fetch-Dest empty Sec-Fetch-Mode cors Sec-Fetch-Site same-site User-Agent Mozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0
更新发现
配置axios.defaults.xsrfHeaderName = "X-CSRFToken";未生效,请求头中未包含对应的字段,如何强制生效或修复该问题?
解决方案
1. 检查跨域与Cookie配置
你的请求是跨端口(8080→8000)的跨域请求,需补充以下Django配置:
# 开发环境下关闭Secure,否则浏览器会拒绝携带Cookie SESSION_COOKIE_SECURE = False CSRF_COOKIE_SECURE = False # 确保CSRF Cookie的SameSite设置和Session一致 CSRF_COOKIE_SAMESITE = None
2. 手动添加CSRF Token到请求头
如果Axios自动配置失效,直接通过全局拦截器或单个请求手动注入Token:
全局拦截器(main.js中添加)
axios.interceptors.request.use(config => { // 从Cookie中提取csrftoken const csrfToken = document.cookie.match(/csrftoken=([^;]+)/)?.[1]; if (csrfToken) { config.headers['X-CSRFToken'] = csrfToken; } return config; }, error => { return Promise.reject(error); });
单个请求手动设置
async function logOut() { try { const csrfToken = document.cookie.match(/csrftoken=([^;]+)/)?.[1]; const response = await axios.post("/api/v1/users/logout/", {}, { headers: { 'X-CSRFToken': csrfToken } }); store.loggedIn = false; store.userID = 0; localStorage.removeItem("account"); window.location.href = "http://localhost:8000"; } catch (error) { console.log(error); } }
3. 验证中间件与信任源
- 确认
django.middleware.csrf.CsrfViewMiddleware位于corsheaders.middleware.CorsMiddleware之后(你的配置已符合) - 检查
CSRF_TRUSTED_ORIGINS是否包含完整源,比如http://localhost:8080不能省略端口
4. 清除缓存与Cookie
直接清除浏览器对应站点的Cookie,重启前后端服务,避免旧缓存干扰配置生效
内容的提问来源于stack exchange,提问作者crawlingdev
相关产品推荐
相关产品推荐

