一丶什么是CSRF?
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