"CSRF令牌丢失或不正确",同时在Django中通过AJAX发布参数

brs*_*gic 61 django jquery django-csrf

我尝试发布参数

 jQuery.ajax(
        {
            'type': 'POST',
            'url': url,
            'contentType': 'application/json',
            'data': "{content:'xxx'}",
            'dataType': 'json',
            'success': rateReviewResult 
        }
    );
Run Code Online (Sandbox Code Playgroud)

但是,Django返回Forbidden 403. CSRF verification failed. Request aborted. 我正在使用,'django.middleware.csrf.CsrfViewMiddleware'并且无法在不影响安全性的情况下找到如何防止此问题.

sig*_*urd 89

您可以通过两种不同的方式发出AJAX帖子请求:

  1. 告诉你的观点不要检查csrf令牌.这可以通过使用装饰器来完成@csrf_exempt,如下所示:

    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
    def your_view_name(request):
        ...
    
    Run Code Online (Sandbox Code Playgroud)
  2. 要在每个AJAX请求中嵌入一个csrf标记,对于jQuery,它可能是:

    $(function () {
        $.ajaxSetup({
            headers: { "X-CSRFToken": getCookie("csrftoken") }
        });
    });
    
    Run Code Online (Sandbox Code Playgroud)

    getCookie函数从饼干CSRF令牌.我使用以下实现:

    function getCookie(c_name)
    {
        if (document.cookie.length > 0)
        {
            c_start = document.cookie.indexOf(c_name + "=");
            if (c_start != -1)
            {
                c_start = c_start + c_name.length + 1;
                c_end = document.cookie.indexOf(";", c_start);
                if (c_end == -1) c_end = document.cookie.length;
                return unescape(document.cookie.substring(c_start,c_end));
            }
        }
        return "";
     }
    
    Run Code Online (Sandbox Code Playgroud)

    此外,jQuery 有一个用于访问cookie 的插件,类似于:

    // set cookie
    $.cookie('cookiename', 'cookievalue');
    // read cookie
    var myCookie = $.cookie('cookiename');
    // delete cookie
    $.cookie('cookiename', null);
    
    Run Code Online (Sandbox Code Playgroud)

  • 重要的是要注意它是"X-CSRFToken"而不是"X-CSRF-Token",它也是常用的 (6认同)
  • 使用`csrf_exempt`装饰器可能会导致安全问题,因为将禁用中间件保护. (2认同)

jer*_*kan 43

我发现最简单的方法是{{csrf_token}}在数据中包含值:

jQuery.ajax(
    {
        'type': 'POST',
        'url': url,
        'contentType': 'application/json',
        'data': {
            'content': 'xxx',
            'csrfmiddlewaretoken': '{{ csrf_token }}',
        },
        'dataType': 'json',
        'success': rateReviewResult 
    }
);
Run Code Online (Sandbox Code Playgroud)

  • 问题是Django没有模仿JS,只有HTML视图. (7认同)
  • 如果你的JavaScript没有被Django处理怎么办?猜猜你真的在小溪上. (5认同)
  • 然后在base.html`window.csrftoken ="{{csrftoken}}"中执行此操作;` (4认同)
  • 最初的问题表明他们正在使用'django.middleware.csrf.CsrfViewMiddleware'并且Django正在返回错误,所以我认为假设Django正在处理ajax请求是相当安全的. (3认同)
  • 他可以在 html 中添加一个 csrf 令牌输入,如果 js 没有被 django 处理,则使用 jquery 来获取该令牌。在表单中添加 `{{ csrf_token }}` 并通过 `csrf_token = $('input[name="csrfmiddlewaretoken"]').val();` 获取值并将其与数据一起传递 `data = {'para1 ':'para1_value',csrfmiddlewaretoken:csrf_token};` (2认同)

tot*_*ico 22

我花了一段时间才明白如何处理Daniel发布的代码.但实际上你所要做的就是将它粘贴在javascript文件的开头.

对我来说,目前最好的解决方案是:

  1. 创建一个csrf.js文件

  2. 将代码粘贴到csrf.js文件中

  3. 在您需要的模板中引用代码

    <script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script>
    
    Run Code Online (Sandbox Code Playgroud)

请注意,STATIC_PREFIX/js/csrf.js指向我的文件.我实际上正在加载STATIC_PREFIX变量{% get_static_prefix as STATIC_PREFIX %}.


高级提示:如果您正在使用模板并具有类似于base.html扩展的位置,那么您可以从那里引用脚本,您不必再担心其余文件.据我了解,这也不代表任何安全问题.

  • 这节省了我几个小时的黑客行为.Django文档中的简单和Pythonic方式. (3认同)

Kha*_*ino 9

简单而简短

$.ajaxSetup({
  headers: { "X-CSRFToken": '{{csrf_token}}' }
});
Run Code Online (Sandbox Code Playgroud)

要么

function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
  beforeSend: function(xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", '{{csrf_token}}');
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

文档


CpI*_*ILL 5

由于缺乏直接答案,您只需将标头添加X-CSRFToken到cookie中的ajax请求中即可csrftoken。如果没有插件,JQuery不会做Cookie(由于某种原因),因此:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

最小的代码更改是:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

  • 一千票的人.....我总是想知道为什么人们不能像这样简单地回答!! (2认同)

Mar*_*dek 5

如果您没有将 js 嵌入到模板中,那么没有任何插件的最快解决方案是:

<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>你的模板里面引用之前的script.js文件,然后添加csrfmiddlewaretoken到您的data字典:

$.ajax({
            type: 'POST',
            url: somepathname + "do_it/",
            data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
            success: function() {
                console.log("Success!");
            }
        })
Run Code Online (Sandbox Code Playgroud)

如果您确实将 js 嵌入到模板中,则很简单: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}