解决Django登录时CSRF cookie未设置的403禁止访问问题
解决Axios调用Django登录接口的CSRF 403问题
后端Django配置调整
先把Django的基础配置捋顺,这是解决问题的核心:
必选中间件检查:打开
settings.py,确认MIDDLEWARE列表里包含django.middleware.csrf.CsrfViewMiddleware,而且必须放在django.contrib.sessions.middleware.SessionMiddleware之后,顺序不能乱:MIDDLEWARE = [ # ...其他中间件 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', # ...其他中间件 ]跨域CORS配置(前后端分离场景):
如果用django-cors-headers处理跨域,确保以下设置正确:INSTALLED_APPS = [ # ... 'corsheaders', # ... ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 这个要放在所有中间件最前面 # ...其他中间件 ] CORS_ALLOW_CREDENTIALS = True # 必须开,允许请求携带Cookie CORS_ORIGIN_WHITELIST = [ 'http://localhost:3000', # 替换成你的前端实际域名,本地开发就写前端端口 # 多个域名就继续加 ] # 本地开发临时测试可以用这个(生产绝对不能开):CORS_ALLOW_ALL_ORIGINS = TrueCookie属性适配环境:
根据部署环境调整Cookie的SameSite和Secure属性:# 本地HTTP开发环境 CSRF_COOKIE_SAMESITE = 'Lax' SESSION_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_SECURE = False SESSION_COOKIE_SECURE = False # 生产HTTPS跨域环境 # CSRF_COOKIE_SAMESITE = 'None' # SESSION_COOKIE_SAMESITE = 'None' # CSRF_COOKIE_SECURE = True # SESSION_COOKIE_SECURE = True优化CSRF Token接口:
你写的/get_csrf_token/接口,加上ensure_csrf_cookie装饰器,确保访问接口时Django自动给浏览器设置csrftokenCookie:from django.views.decorators.csrf import ensure_csrf_cookie from django.http import JsonResponse @ensure_csrf_cookie def get_csrf_token(request): # 可选返回token,其实前端直接从Cookie拿更标准 return JsonResponse({'csrfToken': request.META.get('CSRF_COOKIE')})
前端Axios实现修正
前端要确保正确携带Cookie和CSRF头:
全局开启Cookie携带:
初始化Axios时打开withCredentials,让所有请求都自动携带Cookie:import axios from 'axios'; axios.defaults.withCredentials = true; // 也可以只在单个登录请求里设置withCredentials: true正确提取CSRF Token:
直接从浏览器Cookie里拿csrftoken,别依赖接口返回的内容(避免两边不一致):function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.startsWith(`${name}=`)) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken');设置请求头:
把拿到的Token放到X-CSRFTOKEN请求头里:// 全局设置,所有请求都带这个头 axios.defaults.headers.common['X-CSRFTOKEN'] = csrftoken; // 或者单独给登录请求设置 axios.post('/login/', { username: '你的用户名', password: '你的密码' }, { headers: { 'X-CSRFTOKEN': csrftoken } }) .then(res => { console.log('登录成功', res); }) .catch(err => { console.error('登录失败', err); });
常见问题排查
如果还是报403,按以下步骤查:
- 打开浏览器开发者工具的Network面板,看
/login/请求:- 对比
Request Headers里的X-CSRFTOKEN和Cookies里的csrftoken值是否完全一致; - 确认
Cookie头里确实包含csrftoken;
- 对比
- 检查浏览器有没有禁用Cookie,尤其是跨域场景下的第三方Cookie;
- 确认登录视图没加
csrf_exempt装饰器(登录接口必须受CSRF保护); - 本地开发时,前端和后端的协议要统一(都是HTTP或都是HTTPS),混合协议会导致Cookie带不出去。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

