使用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>
三、关键说明
- Cookie自动设置:
@ensure_csrf_cookie装饰器会在响应中自动添加csrftokenCookie,前端开启withCredentials: true后,浏览器会自动保存该Cookie。 - Axios自动处理CSRF:配置
xsrfHeaderName和xsrfCookieName后,Axios会自动从Cookie中读取csrftoken,并在POST请求时自动添加X-Csrftoken请求头,无需手动操作。 - 跨域配置补充:如果前后端跨域部署,需在Django的
settings.py中添加CORS配置:CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = [ "http://localhost:8080", # 你的Vue项目地址 ]
内容的提问来源于stack exchange,提问作者hello
相关产品推荐
相关产品推荐

