Django之CSRF
CSRF, Cross Site Request Forgery, 跨站偽造請求。舉例來講,某個惡意的網站上有一個指向你的網站的鏈接,如果某個用戶已經登錄到你的網站上了,那麽當這個用戶點擊這個惡意網站上的那個鏈接時,就會向你的網站發來一個請求,你的網站會以為這個請求是用戶自己發來的,其實呢,這個請求是那個惡意網站偽造的。
Django為用戶實現跨站請求偽造保護的功能,通過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對於django中設置防跨站請求偽造功能有分為全局設置和局部設置。
二、Django提供CSRF防護機制
Django第一次響應某個客戶端的請求時,會在服務器端隨機生成一個token,然後把這個token放到cookie中返回給客戶端。然後客戶端每次POST請求時都會帶上這個token,這樣就避免了CSRF攻擊。
在返回的HTTP響應的cookie中,Django會添加一個csrftoken字段,值為隨機生成的token
在POST表單中,必須包含一個csrfmiddlewaretoken隱藏字段,需要在模板中添加{% csrf_token %}自動生成
在處理POST請求之前,Django會驗證cookie中csrftoken和表單中csrfmiddlewaretoken的值是否一致。如果一致,則表明這是一個合法請求。否則這個請求就是偽造的,返回403 Forbidden。
在Ajax POST請求中,添加一個"X-CSRFToken"頭部,值為cookie中的csrftoken的值。
三、CSRF設置
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
四、應用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>
Django之CSRF