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

Django 3.0.x CSRF令牌验证失败问题求助

解决Django 3.0.x中CSRF令牌验证失败的问题

看起来你踩了一个很常见的CSRF令牌使用误区,我来帮你拆解问题并给出具体的解决办法:

核心问题:你误解了_get_new_csrf_token()的作用

_get_new_csrf_token()这个方法的作用是生成一个全新的CSRF令牌,但它不会自动将这个新令牌更新到用户的Cookie中。Django的CsrfViewMiddleware验证逻辑是:对比请求头里的X-CSRFToken和请求Cookie中的csrftoken值是否一致——你用新生成的令牌发请求,但Cookie里还是旧的令牌,自然会触发"Forbidden"错误。

具体解决步骤

1. 改用正确的方式获取有效CSRF令牌

不要生成新令牌,直接从当前请求的Cookie中提取已有的有效令牌:

  • 后端视图中:用request.COOKIES.get('csrftoken')获取当前有效的令牌
  • 前端AJAX中:通过JS读取Cookie中的令牌,推荐用Django官方文档提供的工具函数:
    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.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    const csrftoken = getCookie('csrftoken');
    

2. 修复POSTMAN中的请求配置

你提到request.META里的CSRF_COOKIE和POSTMAN默认Cookie一致,说明POSTMAN自动携带了之前保存的旧Cookie,和你手动设置的新令牌不匹配:

  • 清空POSTMAN请求的Cookie(在请求的"Headers"或"Cookies" tab中删除旧的csrftoken)
  • 先发送一个GET请求到任意受CSRF保护的页面,从响应Cookie中获取csrftoken值
  • 将这个值同时设置到请求头的X-CSRFToken和请求Cookie中,再发送POST请求

3. 检查Django配置的关键项

确保你的settings.py中没有破坏CSRF验证的配置:

  • 确认MIDDLEWARE列表中包含'django.middleware.csrf.CsrfViewMiddleware'(默认是启用的,不要注释它)
  • 检查CSRF_COOKIE_HTTPONLY是否设为False(默认值)——如果设为True,前端JS无法读取Cookie中的令牌,AJAX请求会失败
  • 如果你自定义了CSRF_COOKIE_NAME,确保请求头的X-CSRFToken对应的值是该自定义Cookie中的内容

4. 正确的AJAX请求示例

用原生JS发送POST请求的完整示例:

const csrftoken = getCookie('csrftoken');

fetch('/your-api-endpoint/', {
    method: 'POST',
    headers: {
        'X-CSRFToken': csrftoken,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ /* 你的请求数据 */ })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

总结

本质上是你生成的新令牌没有同步到Cookie中,导致Middleware验证时出现"令牌不匹配"的情况。只要改用Cookie中已有的有效令牌,同时确保请求头和Cookie中的令牌一致,就能解决这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:42:31