📜  如何在 django ajax 中发送 csrf 中间件令牌 - Javascript (1)

📅  最后修改于: 2023-12-03 15:38:14.918000             🧑  作者: Mango

如何在 Django AJAX 中发送 CSRF 中间件令牌 - Javascript

如果你使用 Django 并使用 AJAX 发送 POST 请求,那么你应该知道如何处理 CSRF(Cross-Site Request Forgery,跨站请求伪造)保护。在 Django 中,CSRF 保护是通过 middleware 实现的。在 Django 3.1 以前的版本中,验证 token 是通过 Cookies 实现的。但是,从 Django 3.1 开始,你可以启用 CSRF 来使用更安全的 SameSite Cookie 属性或使用自定义 HTTP 头部标记(X-CSRFToken)。

当使用 AJAX 发送请求时,我们需要将 CSRF 令牌放在请求头部或请求正文中。在本文中,我们将介绍如何在 Django AJAX 中发送 CSRF 令牌。

在 Django 中启用 CSRF 保护

settings.py 中,你需要在 MIDDLEWARE 中添加 django.middleware.csrf.CsrfViewMiddleware

MIDDLEWARE = [
    # ...
    'django.middleware.csrf.CsrfViewMiddleware',
    # ...
]

此外,你还需要在模板中添加 {% csrf_token %} 标记,这将生成一个名为 csrfmiddlewaretoken 的隐藏表单字段,其中包含 CSRF 令牌:

<form method="post">
   {% csrf_token %}
   <!-- other form fields -->
</form>

现在你的 Django 项目已经启用 CSRF 保护,任何 POST 请求都将需要包含 CSRF 令牌。

发送 CSRF 令牌

在 AJAX POST 请求中,我们需要将 CSRF 令牌包含在请求中。有两种方法可以实现:

在请求头中发送 CSRF 令牌

要在请求头中发送 CSRF 令牌,我们需要将 X-CSRFToken 标头设置为令牌值。在通过 AJAX 发送请求前,在 JavaScript 中设置请求头:

// Get CSRF token from cookies
const csrftoken = document.cookie.match('csrftoken=([^;]*)')[1];

// Send AJAX request with CSRF token in header
$.ajax({
  url: '/path/to/your/view/',
  type: 'POST',
  headers: {
    'X-CSRFToken': csrftoken
  },
  data: {
    // request data
  },
  success: function(response) {
    // handle success response
  },
  error: function(xhr, status, error) {
    // handle error response
  }
});

注意上面的代码中,我们从 cookie 中获取 CSRF 令牌,并在请求中包含这个令牌。这里是通过 jQuery 发送的 AJAX 请求,但是其他的框架也可以使用类似的功能。这个方法需要从 cookie 中提取 CSRF 令牌,并将其放置在请求头中。

在请求体中发送 CSRF 令牌

如果你不想从 cookie 中提取 CSRF 令牌,也可以将其包含在请求体中。我们可以将所有请求数据编码成表单数据字符串,包括 CSRF 令牌,然后将其作为 AJAX 请求的数据:

// Get CSRF token from cookies
const csrftoken = document.cookie.match('csrftoken=([^;]*)')[1];

// Build the form data with CSRF token
const formData = new FormData();
formData.append('csrfmiddlewaretoken', csrftoken);
formData.append('data_field_1', 'value_1');
formData.append('data_field_2', 'value_2');

// Send AJAX request with the form data
$.ajax({
  url: '/path/to/your/view/',
  type: 'POST',
  processData: false,
  contentType: false,
  data: formData,
  success: function(response) {
    // handle success response
  },
  error: function(xhr, status, error) {
    // handle error response
  }
});

在这个方法中,我们创建了一个 FormData,然后将 CSRF 令牌和我们要发送的数据添加到表单数据中。当 processDatacontentType 设置为 false 时,jQuery 不会将数据解释为查询字符串,也不会将其设置为 application/x-www-form-urlencoded

总结

在本教程中,我们介绍了如何在 Django AJAX 中发送 CSRF 令牌。我们学习了两种方法:在请求头或请求体中包含 CSRF 令牌。您应该选择最适合您应用程序要求的方法。这样可以帮助您提高应用程序的安全性,也可以确保 Django 项目完全符合最佳安全实践。