CSRF與AJAX
阿新 • • 發佈:2020-08-06
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)