Forbidden (CSRF cookie not set.): “POST /app/uploadcsv/ HTTP/1.1“ 403 2870 403报错解决

文章讲述了在Django中遇到CSRF错误403的原因,涉及CSRF保护机制、如何在前端添加CSRF令牌、禁用或调整CSRF保护设置,以及检查MIDDLEWARE配置。提供了解决此类问题的详细步骤。
摘要由CSDN通过智能技术生成

Forbidden (CSRF cookie not set.): /app/uploadcsv/
[09/Mar/2024 11:51:52] "POST /app/uploadcsv/ HTTP/1.1" 403 2870

这个错误通常是由于 CSRF(Cross-Site Request Forgery)保护机制引起的。Django 默认开启了 CSRF 保护,以防止跨站请求伪造攻击。在 POST 请求中,Django 期望包含一个名为 csrfmiddlewaretoken 的 CSRF 令牌,但你的请求中未包含该令牌,导致服务器返回 403 错误。 

 

为了解决这个问题,可以使用以下方法:

1.在前端添加 CSRF 令牌:在前端代码中,可以使用 Django 提供的模板标签 {% csrf_token %} 来生成 CSRF 令牌,并将其包含在 POST 请求中。示例如下:

<form method="post" action="/app/uploadcsv/">
  {% csrf_token %}
  <!-- 其他表单字段 -->
  <button type="submit">提交</button>
</form>

另外,还有一种可能性是在其他地方手动应用了 CSRF 保护,例如在某些装饰器中或者在其他中间件中。你可以检查一下整个项目的代码,确认是否有其他地方应用了 CSRF 保护。

还有,确保你的浏览器中没有被禁用或者阻止了 Cookie。CSRF 保护是通过在客户端的 Cookie 中存储 CSRF 令牌来实现的,如果浏览器阻止了这些 Cookie,那么服务器就无法验证请求是否合法。

2.禁用 CSRF 保护(不推荐)(如果你已经禁用了CSRF保护仍然报错的话,请看后面):如果你确定你的应用不需要 CSRF 保护,可以在视图函数中使用 @csrf_exempt 装饰器来禁用 CSRF 保护。但这不是推荐的做法,因为会增加安全风险 

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def upload_csv(request):
    # 视图函数代码...

 

3.通过 AJAX 请求获取 CSRF 令牌:如果你使用的是 JavaScript 进行 AJAX 请求,可以通过获取 CSRF 令牌并在请求头中包含它来解决问题。示例如下: 

// 获取 CSRF 令牌
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;

// 发送 AJAX 请求时在请求头中包含 CSRF 令牌
fetch('/app/uploadcsv/', {
  method: 'POST',
  headers: {
    'X-CSRFToken': csrftoken
  },
  // 其他请求参数...
})
.then(response => {
  // 处理响应...
});

 

 4.如果你已经使用了 @csrf_exempt 装饰器,并且仍然遇到 CSRF 错误,那么问题可能不在于 CSRF 保护。错误可能是由其他原因引起的。

有一种可能性是,即使你在视图函数上使用了 @csrf_exempt 装饰器,Django 仍然在全局中启用了 CSRF 中间件。这可能是由于在 MIDDLEWARE 设置中包含了 django.middleware.csrf.CsrfViewMiddleware 导致的。你可以尝试将它从 MIDDLEWARE 设置中移除或者将其移到 MIDDLEWARE 设置的底部,以确保在视图函数调用之前不会执行 CSRF 检查。

你可以打开项目中的 settings.py 文件,并检查 MIDDLEWARE 设置。确保 django.middleware.csrf.CsrfViewMiddleware 中间件的位置。通常,这个中间件应该在列表中的较前位置,但不要放在第一个位置。例如:

MIDDLEWARE = [
    # 其他中间件...
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',  # 可以把这个注释掉
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

如果 django.middleware.csrf.CsrfViewMiddleware 中间件已经在 MIDDLEWARE 设置中了,你可以考虑将它移到列表的底部,这样可以确保在视图函数调用之前不会执行 CSRF 检查。

如果在 MIDDLEWARE 设置中没有找到 django.middleware.csrf.CsrfViewMiddleware 中间件,那么可能是在其他地方手动应用了 CSRF 保护,比如在某些视图函数的装饰器中。在这种情况下,你需要检查整个项目的代码,确认是否有其他地方应用了 CSRF 保护。

5.如果你只是在练习,或者做一些简单项目,可以删去上面提到的 django.middleware.csrf.CsrfViewMiddleware 中间件,这样就不会报403错误了,但可能带来安全风险。

这个中间件的作用是为每个包含表单的页面添加 CSRF 令牌,并在提交表单时验证这些令牌,以防止跨站请求伪造 (CSRF) 攻击。如果你删除了这个中间件,那么你的应用将不再具有 CSRF 保护,这会使你的应用更容易受到 CSRF 攻击。

如果你决定删除 django.middleware.csrf.CsrfViewMiddleware 中间件,请确保你的应用没有任何表单提交或其他需要 CSRF 保护的功能。另外,你可能需要在你的代码中实现其他方式的 CSRF 保护,例如使用 AJAX 请求时在请求头中添加 CSRF 令牌。

最好的做法是只在确保没有表单提交或其他需要 CSRF 保护的功能时才删除这个中间件。如果你的应用中仍然存在需要保护的功能,那么最好保留这个中间件,以确保应用的安全性。

 

这个错误是由于DjangoCSRF保护机制引起的,它需要确保每个POST请求都具有与会话关联的CSRF令牌。 在Django中,每个POST请求都需要在请求中包含一个名为`csrfmiddlewaretoken`的CSRF令牌。如果请求中不包含这个令牌,Django会抛出`Forbidden (CSRF cookie not set.)`错误。 为了解决这个问题,您需要在POST请求的表单中包含CSRF令牌。例如,在您的HTML表单中,可以添加以下代码: ```html {% csrf_token %} ``` 这将在表单中添加一个隐藏字段,其中包含与当前会话关联的CSRF令牌。当用户提交表单时,这个令牌将与请求一起发送,以通过CSRF保护。 如果您使用的是AJAX请求,可以将CSRF令牌作为请求头发送。例如,在JavaScript中,可以添加以下代码: ```javascript 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 = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrfToken = getCookie('csrftoken'); $.ajax({ ... headers: { 'X-CSRFToken': csrfToken }, ... }); ``` 这将在请求头中添加一个名为`X-CSRFToken`的头,其中包含与当前会话关联的CSRF令牌。这样,您的AJAX请求将通过CSRF保护。 请注意,如果您使用的是第三方库或框架,例如Django REST framework或jQuery,它们可能会自动处理CSRF令牌。在这种情况下,您不需要手动添加CSRF令牌。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值