1. 程式人生 > 實用技巧 >CSRF與AJAX

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)