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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:57:04