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>
~~~