1、什麼是CSRFjavascript
CSRF, Cross Site Request Forgery, 跨站僞造請求。舉例來說,某個惡意的網站上有一個指向你的網站的連接,若是某個用戶已經登陸到你的網站上了,那麼當這個用戶點擊這個惡意網站上的那個連接時,就會向你的網站發來一個請求,你的網站會覺得這個請求是用戶本身發來的,其實呢,這個請求是那個惡意網站僞造的。前端
Django爲用戶實現跨站請求僞造保護的功能,經過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對於django中設置防跨站請求僞造功能有分爲全局設置和局部設置。java
2、Django提供CSRF防禦機制python
Django第一次響應某個客戶端的請求時,會在服務器端隨機生成一個token,而後把這個token放到cookie中返回給客戶端。而後客戶端每次POST請求時都會帶上這個token,這樣就避免了CSRF***。
jquery
在返回的HTTP響應的cookie中,Django會添加一個csrftoken字段,值爲隨機生成的tokenajax
在POST表單中,必須包含一個csrfmiddlewaretoken隱藏字段,須要在模板中添加{% csrf_token %}自動生成django
在處理POST請求以前,Django會驗證cookie中csrftoken和表單中csrfmiddlewaretoken的值是否一致。若是一致,則代表這是一個合法請求。不然這個請求就是僞造的,返回403 Forbidden。服務器
在Ajax POST請求中,添加一個"X-CSRFToken"頭部,值爲cookie中的csrftoken的值。cookie
3、CSRF設置ide
1. 全局設置(中間件)
django.middleware.csrf.CsrfViewMiddleware
2. 局部設置(視圖函數)
from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_protect # 爲當前函數強制設置防跨站請求僞造功能,即使settings中沒有設置CSRF中間件。 def func(): pass @csrf_exempt # 取消當前函數防跨站請求僞造功能,即使settings中設置了CSRF中間件。 def func(): pass
4、應用CSRF
1. 前端Form表單中設置CSRF
<form method="post"> {% csrf_token %} ... </form>
2. 自動在每一個Ajax請求頭部中添加"X-CSRFToken"
// 導入jquery.cookie.js 經過$.cookie('csrftoken')獲取csrf_token // beforeSend在每一個Ajax請求以前自動設置請求頭部"X-CSRFToken" <script src="/static/plugin/jquery/jquery-1.8.0.js"></script> <script src="/static/plugin/jquery/jquery.cookie.js"></script> <script type="text/javascript"> var csrftoken = $.cookie('csrftoken'); 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", csrftoken); } } }); </script>
3. 單獨在Ajax請求中設置"X-CSRFToken"頭部
<script src="/static/plugin/jquery/jquery-1.8.0.js"></script> <script src="/static/plugin/jquery/jquery.cookie.js"></script> <script type="text/javascript"> $.ajax({ headers:{"X-CSRFToken":$.cookie('csrftoken')}, ... }) </script>