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

使用Django+Vue实现登录时出现CSRF cookie not set错误求助

你的问题核心在于手动处理CSRF token的逻辑和Django、Axios的自动机制冲突,同时视图层的Cookie设置逻辑有冗余。以下是具体修正方案:

一、修正Django视图(views.py)

@ensure_csrf_cookie装饰器会自动给响应设置csrftoken Cookie,不需要手动在响应头添加x-csrftoken,冗余代码反而会导致Cookie设置异常。另外登录视图需要统一返回格式并处理请求方法:

from django.http import JsonResponse
from django.contrib.auth import authenticate, login
from django.views.decorators.csrf import ensure_csrf_cookie

def loginView(request):
    if request.method != 'POST':
        return JsonResponse({'detail': 'Method not allowed'}, status=405)
    
    # 用get避免KeyError,增强鲁棒性
    username = request.POST.get('username')
    password = request.POST.get('password')
    
    if not username or not password:
        return JsonResponse({'detail': 'Username and password are required'}, status=400)
    
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        return JsonResponse({'detail': 'OK'})
    else:
        return JsonResponse({'detail': 'Invalid username or password'}, status=401)
    
@ensure_csrf_cookie
def getToken(request):
    # 只需要返回基础响应,@ensure_csrf_cookie会自动设置csrftoken Cookie
    response = JsonResponse({'detail': 'csrf cookie set'})
    # 允许前端读取响应头里的CSRF token(可选,因为Axios会自动从Cookie取)
    response['Access-Control-Expose-Headers'] = 'X-Csrftoken'
    return response

二、修正Vue组件(login.vue)

Axios已经配置了自动从Cookie读取csrftoken并添加到请求头,不需要手动获取token再设置。简化登录逻辑,先触发Cookie设置再发送登录请求:

<template>
  <div class="hello">
    <div class="title-color">This is a Login page.</div>
    <div class="form-container">
        <form v-on:submit.prevent="handleLogin">
          <h2>Login</h2>
          <div class="form-group">
            <label class="label">username</label>
            <input class="input" type="text" v-model="username" /><br>
          </div>
          <div class="form-group">
            <label class="label">password</label>
            <!-- 密码框建议用type="password"提升安全性 -->
            <input class="input" type="password" v-model="password" /><br>
          </div>
          <button class="button" type="submit">Submit</button>
        </form>
    </div>
  </div>
</template>

<script>
import axios from "axios";

// Axios全局配置保持正确设置
axios.defaults.xsrfHeaderName = 'X-Csrftoken'
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.withCredentials = true;

export default {
  name: "LoginView",
  props: {
    msg: String,
  },
  data() {
    return {
      username: "",
      password: "",
    };
  },
  methods: {
    handleLogin() {
      // 先发送GET请求触发CSRF Cookie设置
      axios.get("http://127.0.0.1:8000/csrf/", {
        auth: {
          username: "你的认证用户名",
          password: "你的认证密码",
        },
      }).then(() => {
        // Cookie已自动保存,Axios会自动带上CSRF请求头,直接发送登录请求
        return axios.post("http://127.0.0.1:8000/login/", {
          username: this.username,
          password: this.password,
        }, {
          auth: {
            username: "你的认证用户名",
            password: "你的认证密码",
          },
        })
      }).then((response) => {
        console.log("登录成功:", response);
      }).catch((error) => {
        console.error("登录失败:", error.response.data);
      })
    },
  }
};
</script>

三、关键说明

  1. Cookie自动设置:@ensure_csrf_cookie装饰器会在响应中自动添加csrftoken Cookie,前端开启withCredentials: true后,浏览器会自动保存该Cookie。
  2. Axios自动处理CSRF:配置xsrfHeaderName和xsrfCookieName后,Axios会自动从Cookie中读取csrftoken,并在POST请求时自动添加X-Csrftoken请求头,无需手动操作。
  3. 跨域配置补充:如果前后端跨域部署,需在Django的settings.py中添加CORS配置:
    CORS_ALLOW_CREDENTIALS = True
    CORS_ALLOWED_ORIGINS = [
        "http://localhost:8080",  # 你的Vue项目地址
    ]
    

内容的提问来源于stack exchange,提问作者hello

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:26:04