方式一:
django模板標簽提供{% csrf_token %}在前端生成input框,如果在settings.py文件中開啟了該中間件,每次post請求就需要提交django自動生成的csrfToken;
將{% csrf_token %}生成的input框的value通過ajax傳參來提交;
{% csrf_token %} <!-- django模板標簽提供的csrf_token值,會自動生成一個input框--> <script> $("#button_name").on("click",function{ var name = $("#name").val(); var csrfToken = $("[name="csrfmiddlewaretoken"]").val(); $.ajax({ url: "/ajax_res/", // 請求視圖 type: "post", // 請求方式 // 攜帶數據,從{% csrf_token %}input框中獲取csrfToken值,通過ajax方式提交后台,否則報錯:Forbidden(CSRF token missing or incorrect.) data: {"name": name, "csrfmiddlewaretoken": csrfToken} success: function(args){ alert(args) // 返回數據 //... } }); }); </script>
方式二:
從獲取當前頁面的get請求的響應中cookie里獲取csrfToken,再寫入當前post請求的請求頭中;
需要引入:jquery.cookie.js插件
<script> $.ajax({ url: "/ajax_res/", type: "post", headers: {"X-CSRFToken":$.cookie("csrftoken")}, data: {"name": name} success: function(args){ alert(args) //... } }); </script>
方式三:
與方式二原理相同,手寫從cookie中獲取/寫入csrfToken的js文件,再引入,就不需要做其他參數傳遞,同get請求一般;
// ajaxSetup.js
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'); // 2.定義不需要csrftoken的請求方式 function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } // 3.將csrftoken寫入當前請求頭 $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
方式四:
在ajax請求前加上;
<script> $.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}'}, }); </script>
下面講述django中csrf的使用:
django中csrf_token有兩種提交方式,一種是在template模板中使用{% csrf_token %}生成一個input框在form表單中提交或者將csrf_token值通過ajax提交;
一種是將csrf寫入cookie中;
就是上面講述的方式;
在django中開啟csrf跨站請求保護:
1.開啟django.middleware.csrf.CsrfViewMiddleware中間鍵(django默認在settings.py中已經開啟了);
2.將1.中的中間鍵注釋掉,對指定視圖添加跨站請求保護,通過django.views.decorators.csrf import csrf_protect裝飾器來啟用當前視圖(@csrf_protect);
在django中其他與csrf有關的裝飾器:
1.csrf_exempt(view)裝飾器,免除csrf跨站保護;
使用場景:大部分視圖需要保護,小部分不需要,開啟CsrfViewMiddleware中間鍵,同時使用csrf_exempt(view)免除不需要保護的視圖;
2.requires_csrf_token(view)裝飾器,用以確認前端form表單中是否通過{% csrf_token %}傳遞值過來,但是不拒絕請求;
使用場景01:在某些情況下,比如CsrfViewMiddleware.process_view沒有在視圖運行前執行,造成404/500等錯誤(拒絕請求),但是我們仍然需要csrf_token的值做一些其他的處理,
就可以使用requires_csrf_token(view)(不拒絕請求);
使用場景02:與場景01不同,不是某些異常情況,而是本身當前視圖就不需要保護,但是仍然需要使用csrf_token做一些判斷處理,就可以使用requires_csrf_token(view)與csrf_exempt(view)
來實現,注意是先執行requires_csrf_token(view)裝飾器(csrf_exempt(view)寫在上面);
@csrf_exempt
@requires_csrf_token
def index_view:
3.ensure_csrf_cookie(view)裝飾器,表示當前視圖請求必須將csrf寫在cookie中;
csrf的注意事項:
如果django中開啟了緩存中間件,單獨使用cache_page(view)緩存裝飾器的視圖中跨站請求保護將會失效,需要在cache_page(view)前執行csrf_protect(view)裝飾器;
@cache_page(60*15)
@csrf_protect
def index_view...