CSRF是Cross Site Request Forgery的缩写,翻译过来就是跨站请求伪造。那么什么是跨站请求伪造呢?让我一个词一个词的解释:
1、跨站:顾名思义,就是从一个网站到另一个网站。
2、请求:即HTTP请求。
3、伪造:在这里可以理解为仿造、伪装。
综合起来的意思就是:从一个网站A中发起一个到网站B的请求,而这个请求是经过了伪装的,伪装操作达到的目的就是让请求看起来像是从网站B中发起的,也就是说,让B网站所在的服务器端误以为该请求是从自己网站发起的,而不是从A网站发起的。当然,请求一般都是恶意的。
django为用户实现防止跨站请求伪造的功能,通过中间件django.middleware.csrf.CsrfViewMiddleware 来完成。
对于django中设置防跨站请求伪造功能分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_protect,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
默认(全局):'django.middleware.csrf.CsrfViewMiddleware' 中间间,过滤所有post的请求。是为全局的,需要遵循下面
在html中加上{% csrf_token %}
views:的返回用render方法
去掉(全局):'django.middleware.csrf.CsrfViewMiddleware'就不需要遵循csrf
设置(局部)也可以通过装饰器来设定局部的CSRF。(指定某些遵循csrf)
@csrf_protect
在html中加上{% csrf_token %}
views:的返回用render
使用装饰器也可以(局部)不遵循CSRF(指定某些不遵循csrf)
@csrf_exempt
1丶普通表单
1 veiw中设置返回值:
2 return render_to_response('Account/Login.html',data,context_instance=RequestContext(request)) <br> # render_to_response需要context_instance=RequestContext(request)这个参数,因为render_to_response不生成随机字符串。
3 或者 return render(request, 'xxx.html', data) html中设置Token: {% csrf_token %}
2丶Ajax
对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。
from django.template.context import RequestContext
# Create your views here.
def test(request):
if request.method == 'POST':
print request.POST
return HttpResponse('ok')
return render_to_response('app01/test.html',context_instance=RequestContext(request))
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
{% csrf_token %}
<input type="button" onclick="Do();" value="Do it"/>
<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({ // 是一个全局的配置,在所有的ajax发来之前执行
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
// 在发ajax之前设置一个请求头,名字是X-CSRFToken,
// 在ajax发送之前把请求头放到csrftoken,在一块发过去,对的就执行
}
}
});
// 上面是获取token,在以后ajax操作前,写上面这个配置。
function Do(){
$.ajax({
url:"/app01/test/",
data:{id:1},
type:'POST',
success:function(data){
console.log(data);
}
});
}
</script>
</body>
</html>
更多:https://docs.djangoproject.com/en/dev/ref/csrf/#ajax