【问题标题】:django/ajax CSRF token missingdjango/ajax CSRF 令牌丢失
【发布时间】:2018-09-07 13:05:33
【问题描述】:

我有以下 ajax 函数,一旦我使用 select2 控件超过 3 的最小长度输入,它就会给我一个跨站点伪造请求令牌错误。知道这一点后,我尝试将 { csrfmiddlewaretoken: '{{ csrf_token }}' } 添加到我的数据中:。添加 csrfmiddlewaretoken 后,我仍然收到 CSRF 令牌丢失或不正确的错误。我相信这与我对 searchFilter 和 searchPage 的功能有关。这样做的正确方法是什么?

// using jQuery
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;
}
var csrftoken = getCookie('csrftoken');

$(document).ready(function () {
    $('.selectuserlist').select2({
      minimumInputLength: 3,
      allowClear: true,
      placeholder: {
        id: -1,
        text: 'Enter the 3-4 user id.',
      },
      ajax: {
        type: 'POST',
        url: '',
        contentType: 'application/json; charset=utf-8',
        async: false,
        dataType: 'json',
        data: { csrfmiddlewaretoken: csrftoken },

        function(params) {
          return "{'searchFilter':'" + (params.term || '') + "','searchPage':'" + (params.page || 1) + "'}";
        },

        processResults: function (res, params) {
            var jsonData = JSON.parse(res.d);
            params.page = params.page || 1;
            var data = { more: (jsonData[0] != undefined ? jsonData[0].MoreStatus : false), results: [] }, i;
            for (i = 0; i < jsonData.length; i++) {
              data.results.push({ id: jsonData[i].ID, text: jsonData[i].Value });
            }

            return {
              results: data.results,
              pagination: { more: data.more,
              },
            };
          },
      },
    });

  });

我的视图也有 POST 方法和 csrf_token。

  {% block content %}
  <form action = "{% url 'multiresult' %}" form method = "POST">
      {% csrf_token %}
  {% block extra_js %}
      {{ block.super }}
      {{ form.media }}

控制台的响应是

禁止(CSRF 令牌丢失或不正确。):/search/multisearch/ [29/Mar/2018 09:14:52]“POST /search/multisearch/HTTP/1.1”403 2502

【问题讨论】:

  • Django 文档解释了如何设置标题for ajax requests。由于你的ajax请求提交的是json编码的数据,所以你必须使用那个方法。

标签: ajax django jquery-select2


【解决方案1】:

您必须包含 csrf_token 作为标题:

var csrftoken = $("[name=csrfmiddlewaretoken]").val();

//example ajax
$.ajax({
    url: url,
    type: 'POST',
    headers:{
        "X-CSRFToken": csrftoken
    },
    data: data,
    cache: true,
});

如果您不在 ssl 上,还要确保 CSRF_COOKIE_SECURE = False。 如果您使用的是 ssl,请将其设置为 True

是否为 CSRF cookie 使用安全 cookie。如果设置为 True,cookie 将被标记为“安全”,这意味着浏览器可以确保 cookie 仅通过 HTTPS 连接发送。

【讨论】:

  • 我可以将 CSRF_COOKIE_SECURE 添加到我的 settings.py 中吗?我没有使用 SSL。
  • 是的,将其添加到设置中
  • 我按照你的建议做了,它纠正了我的 CSRF 错误。我的结果是另一个问题,感谢您将我引向正确的方向。
  • 没问题 :) 很高兴我能提供帮助
【解决方案2】:

JS 和 Django 模板语言的混合帮助解决了这个问题。

  $.ajax({
         type: 'POST',
         headers:{
        "X-CSRFToken": '{{ csrf_token }}'
         }
  })

【讨论】:

    【解决方案3】:

    只是更改了下面的代码行,它更简单,因为您不必涉及模板。你提供的js sn-p已经有了csrf值。

      data: { csrfmiddlewaretoken: '{{ csrf_token }}' },
          // INTO
      data: { csrfmiddlewaretoken: csrftoken },
    

    【讨论】:

    • 我已经按照你的建议做了,但我仍然遇到同样的 403 错误问题。我已经添加了上面的更改。
    • 此外,一旦 select2 控件中的 minimumlengthinput 满足 3,就会发生 403 错误。
    猜你喜欢
    • 1970-01-01
    • 2017-09-14
    • 2021-07-14
    • 1970-01-01
    • 2020-11-23
    • 2020-10-12
    • 2021-11-13
    • 2012-04-20
    • 2012-09-25
    相关资源
    最近更新 更多