CSRF与AJAX

1. form表单

在含有POST表单的模板中,需要在其<form>表单元素内部添加csrf_token标签,如下所示:

<form action="" method="post">
    {% csrf_token %}
    ....
</form>

2.  Ajax提交

①在你的前端模版的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 = 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');

function csrfSafeMethod(method) {
    // 这些HTTP方法不要求CSRF包含
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

然后再写ajax表单请求

$.ajax({
            url: xx,
            type: 'POST',
            data: {
     
            },
            success: function (res) {
                        } )

② 直接在主界面写{% csrf_token %}, 因为没有form表单,所以写那个位置都行

然后直接data引用

$.ajax({
            url: xx,
            type: 'POST',
            data: {
                'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()
            },

2.装饰器

①单独指定csrf验证需要

有时候,我们在全站上关闭了CSRF功能,但是希望某些视图还有CSRF防御,那怎么办呢?

Django为我们提供了一个csrf_protect(view)装饰器,使用起来非常方便,如下所示:

from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render

@csrf_protect
def index_view(request):
    return render(request, "template.html")

②单独指定忽略csrf验证

有正就有反。在全站开启CSRF机制的时候,有些视图我们并不想开启这个功能。比如,有另外一台机器通过requests库,模拟HTTP通信,以POST请求向我们的Django主机服务器发送过来了一段保密数据。它无法携带CSRF令牌,必然会被403。

这怎么办呢?

在接收这个POST请求的视图上为CSRF开道口子,不进行验证。这就需要使用Django为我们提供的csrf_exempt(view)装饰器了,下面是使用范例:

from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

@csrf_exempt
def index_view(request):
    return HttpResponse('Hello world')

③确保csrf令牌被设置

Django还提供了一个装饰器,确保被装饰的视图在返回页面时同时将csrf令牌一起返回。

这个装饰器是:ensure_csrf_cookie(view),其使用方法和上面的一样:

from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponse

@ensure_csrf_cookie
def index_view(request):
    return HttpResponse('Hello world')

④requires_csrf_token(view)

这个装饰器类似csrf_protect,一样要进行csrf验证,但是它不会拒绝发送过来的请求。

 

from django.views.decorators.csrf import requires_csrf_token
from django.shortcuts import render

@requires_csrf_token
def index_view(request):
    return render(request, "a_template.html", c)

 

posted on 2020-08-06 14:58  沈家大大  阅读(145)  评论(0编辑  收藏  举报