CSRF(Cross-site request forgery跨站請求偽造,也被稱為"One Click Attack"或者Session Riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用。
盡管聽起來像跨站腳本(XSS),但它與XSS非常不同,并且攻擊方式幾乎相左。XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。
## 簡介
django為用戶實現防止跨站請求偽造的功能,通過中間件 `django.middleware.csrf.CsrfViewMiddleware` 來完成。而對于django中設置防跨站請求偽造功能有分為全局和局部。
### 全局
中間件 django.middleware.csrf.CsrfViewMiddleware
### 局部
`@csrf_protect`,為當前函數強制設置防跨站請求偽造功能,即便settings中沒有設置全局中間件。
`@csrf_exempt`,取消當前函數防跨站請求偽造功能,即便settings中設置了全局中間件。
注:`from django.views.decorators.csrf import csrf_exempt,csrf_protect`
## 應用
`csrf_token`可以從網頁源代碼中獲取到,也可以從`cookie`中獲取到(`key:csrftoken`)。
### 普通form表單
在普通的form表單中,只需要將`{% csrf_token %}`加在form中,form表單提交時會自動`csrf_token`。
### 針對單一ajax
~~~
<script type="text/javascript">
$(function () {
var csrftoken = $.cookie('csrftoken');
$('#id').click(function (){
$.ajax({
url:"/app01/test/",
data:{id:1, "X-CSRFToken", csrftoken},
type:'POST',
success:function(data){
console.log(data);
}
});
};
}
</script>
~~~
### 針對多個ajax全局設置
所有ajax執行前都會附加上`csrftoken`。
~~~
<script type="text/javascript">
$(function () {
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);
}
}
});
var csrftoken = $.cookie('csrftoken');
$('#id').click(function (){
$.ajax({
url:"/app01/test/",
data:{id:1},
type:'POST',
success:function(data){
console.log(data);
}
});
}
}
</script>
~~~