django 解决ajax 请求csrf跨域问题,解决403 forbidden

本文介绍了解决Django项目中因CsrfViewMiddleware导致的403跨域错误的方法。通过使用JavaScript获取csrftoken,并在AJAX POST请求中加入csrfmiddlewaretoken键值对,实现跨域请求的正确处理。

现象: 请求403 ,提示跨域

原因:

项目setting.py 中installed app 里面有

'django.middleware.csrf.CsrfViewMiddleware',

###解决过程:查看请求发现 cookie 有csrftoken
所以利用js 获取csrftoken

核心语句   document.cookie()会返回所有的cookie 
cookie 的结构如下: name1=value1;name2=value2
所以遍历每一项cookie 找到csrftoken的value

具体代码:

function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                     }
                    }
                 }
             return cookieValue;
            }

最后在ajax post 中传入一个key为csrfmiddlewaretoken

$.ajax({
	type:"POST",
	data:{"csrfmiddlewaretoken": csrftoken_value, key2:value2}
})
<think>我们正在解决Django中由于CSRFtoken缺失导致的Forbidden(403)错误。用户之前的问题是关于静态文件标签库的,但当前问题已经转向CSRFtoken缺失问题。根据Django官方文档,当POST请求中缺少CSRFtoken时,会引发CSRF验证失败,返回403Forbidden错误。解决方案步骤:1.确保在模板的表单中包含{%csrf_token%}标签。2.检查Django中间件配置,确保'django.middleware.csrf.CsrfViewMiddleware'已启用。3.对于AJAX请求,需要手动添加CSRFtoken到请求头中。4.如果使用基于类的视图,确保使用@method_decorator(csrf_exempt)(如果需要豁免)或正确处理。我们将逐步解释这些解决方案。</think>### 解决DjangoCSRF Token缺失导致的Forbidden错误 当Django返回**"CSRF token missing or incorrect. Forbidden (403)"**错误时,表明服务器未能验证请求来源的安全性。以下是系统化的解决方案: --- #### 核心原因分析 1. **表单缺少CSRF Token** 提交表单时未包含`{% csrf_token %}`标签 2. **中间件未启用** `CsrfViewMiddleware`未在中间件配置中激活 3. **AJAX请求未携带Token** JavaScript请求未正确设置CSRF Token头部 4. **Cookie不匹配** 请求时Cookie与当前不一致 --- #### 解决方案步骤 ##### 1. 基础修复:确保模板包含CSRF Token 在**所有HTML表单**中添加Token标签: ```django <form method="post"> {% csrf_token %} <!-- 必须添加此行 --> <!-- 其他表单字段 --> <input type="submit" value="Submit"> </form> ``` > 验证方法:查看页面源代码,确认存在`<input type="hidden" name="csrfmiddlewaretoken" value="...">` ##### 2. 检查中间件配置 在`settings.py`中确认中间件链包含: ```python MIDDLEWARE = [ ... 'django.middleware.csrf.CsrfViewMiddleware', # 必须存在 ... ] ``` > 位置要求:需在`SessionMiddleware`之后,`AuthenticationMiddleware`之前[^1] ##### 3. 处理AJAX请求(JavaScript方案) 使用以下代码为所有AJAX请求添加CSRF Token: ```javascript // 使用jQuery示例 $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) { xhr.setRequestHeader("X-CSRFToken", getCookie("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.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } ``` ##### 4. 解决问题(CORS配置) 在`settings.py`中添加: ```python CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", # 前端开发地址 "https://your-production-domain.com", ] CSRF_TRUSTED_ORIGINS = CORS_ALLOWED_ORIGINS # 同步信任源 SESSION_COOKIE_SAMESITE = 'None' # Cookie SESSION_COOKIE_SECURE = True # 仅HTTPS ``` ##### 5. 豁免特定视图(谨慎使用) 在视图上添加豁免装饰器: ```python from django.views.decorators.csrf import csrf_exempt @csrf_exempt # ⚠️ 仅用于测试或内部API def my_view(request): ... ``` --- #### 调试流程 1. **检查请求头** 使用浏览器开发者工具,查看请求是否包含: - `Cookie: csrftoken=...` - `X-CSRFToken: ...` (AJAX请求) 2. **验证中间件顺序** 运行检查命令: ```bash python manage.py check --deploy --fail-level WARNING ``` 3. **测试CSRF保护状态** 在Django shell中验证: ```python from django.middleware.csrf import get_token request = HttpRequest() print(get_token(request)) # 应输出有效token ``` --- #### 完整配置示例 ```python # settings.py MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', # 关键位置 'django.contrib.auth.middleware.AuthenticationMiddleware', ... ] CORS_EXPOSE_HEADERS = ['Content-Type', 'X-CSRFToken'] CSRF_COOKIE_HTTPONLY = False # 允许JS读取Cookie ``` ```html <!-- 模板文件 --> <script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; // 用于AJAX请求头 </script> ``` --- #### 生产环境注意事项 1. 确保`DEBUG = False`时仍能正确处理静态文件 2. 使用HTTPS协议传输CSRF Token 3. 定期轮换`SECRET_KEY`增强安全性 4. 对公开API使用Token认证替代CSRF > 官方建议:CSRF保护应始终启用,仅对无需状态保持的API豁免[^2] --- ### 相关问题 1. 如何在Django REST Framework中处理CSRF验证? 2. CSRF Token和JWT Token有何本质区别? 3. 为什么有时在Django中需要同时使用CORS和CSRF中间件? 4. 如何测试Django应用的CSRF防护有效性? [^1]: Django官方中间件文档 - CSRF保护机制 [^2]: OWASP安全指南 - CSRF防护最佳实践
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值