目录html
中间件就是介于request与response处理之间的一道处理过程,相对比较轻量级,而且在全局上改变django的输入与输出。由于改变的是全局,因此须要谨慎使用。python
Django中间件的定义:jquery
Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.
django的中间件,其实就是一个类,在请求到来和结束后,django会根据本身的规则在合适的时机执行中间件中相应的方法,因此若是须要修改请求,例如被传送到view中的HttpRequest对象,或者是修改view返回的HttpResponse对象,就能够经过中间件来实现。ajax
Django默认的中间件:django
在django项目的settings模块中,有一个MIDDLEWARE变量浏览器
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
请求传递到Django的过程以下:服务器
中间件的五个方法cookie
process_request(self,request) process_view(self, request, callback, callback_args, callback_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response)
中间件方法的运行流程图:session
第一步:导入MiddlewareMixinapp
from django.utils.deprecation import MiddlewareMixin
第二步:自定义中间件
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class MyMiddelware1(MiddlewareMixin): def process_request(self, request): print('MyMiddelware1=====>request') def process_response(self, request, response): print('MyMiddelware1======>response') # 返回response return response class MyMiddelware2(MiddlewareMixin): def process_request(self, request): print('MyMiddelware2=====>request') def process_response(self, request, response): print('MyMiddelware2======>response') # 返回response return response
第三步:在view中定义一个视图函数
def index(request): print('视图函数') return HttpResponse('aaa')
第四步:在settings.py的MIDDLEWARE里注册本身定义的中间件
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'app01.mymiddelware.MyMiddelware1', 'app01.mymiddelware.MyMiddelware2', ]
结果:
MyMiddelware1=====>request MyMiddelware2=====>request 视图函数 MyMiddelware2======>response MyMiddelware1======>response
注意:若是当请求到达process_request的直接不符合条件返回,程序将把请求直接发给其对应的process_response返回.而后依次返回到请求者,结果以下:
MyMiddelware1=====>request MyMiddelware2=====>request MyMiddelware2======>response MyMiddelware1======>response
总结:
1.中间件的preocess_request方法是在执行视图函数以前执行的 2.当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的 3.不一样中间件之间传递的request都是同一个对象
process_view(self,request,callback, callback_args, callback_kwargs)
该方法由四个参数:
Django会在调用视图函数以前调用process_view方法
它应该返回None或一个HttpResponse对象。 若是返回None,Django将继续处理这个请求,执行任何其余中间件的process_view方法,而后在执行相应的视图。 若是它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。
process_exception(self,request,exception)
该方法有两个参数:
这个方法只有在视图函数中出现异常了才执行,它返回的值能够是一个None也能够是一个HttpResponse对象。若是是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,不然将默认处理异常。若是返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
process_template_response(self,request,response)
该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,一般缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS很是不一样,XSS利用站点内的信任用户,而CSRF则经过假装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击每每不大流行(所以对其进行防范的资源也至关稀少)和难以防范,因此被认为比XSS更具危险性 能够这样来理解: 攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来讲这个请求是彻底合法的,可是却完成了攻击者所指望的一个操做,好比以你的名义发送邮件、发消息,盗取你的帐号,添加系统管理员,甚至于购买商品、虚拟货币转帐等。 以下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户
1.验证HTTP Referer字段 2.在请求地址中添加token并验证(Django处理方式) 3.在HTTP头中自定义属性并验证
<form action="" method="post"> {% csrf_token %} <p>用户名:<input type="text" name="name"></p> <p>密码:<input type="text" name="pwd"></p> <input type="submit" value="提交"> </form>
<script> $(".btn").click(function () { $.ajax({ url: '', type: 'post', data: { 'name': $('[name="name"]').val(), 'password': $("#pwd").val(), 'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val() 'csrfmiddlewaretoken':'{{ csrf_token }}' }, success: function (data) { console.log(data) } }) }) </script>
获取cookie:document.cookie
是一个字符串,能够本身用js切割,也能够用jquery插件
获取cookie:$cookie('csrftoken')
设置cookie:$cookie('key','value')
<script> $(".btn").click(function () { var token=$.cookie('csrftoken') //var token='{{ csrf_token }}' $.ajax({ url: '', headers:{'X-CSRFToken':token}, type: 'post', data: { 'name': $('[name="name"]').val(), 'password': $("#pwd").val(), }, success: function (data) { console.log(data) } }) }) </script>
全局禁用:注释掉中间件 'django.middleware.csrf.CsrfViewMiddleware',
局部禁用:使用装饰器,导入from django.views.decorators.csrf import csrf_exempt,csrf_protect
在FBV中使用:
from django.views.decorators.csrf import csrf_exempt,csrf_protect # 再也不检测,局部禁用(前提是全站使用) # @csrf_exempt # 检测,局部使用(前提是全站禁用) # @csrf_protect def csrf_token(request): if request.method=='POST': print(request.POST) return HttpResponse('ok') return render(request,'csrf_token.html')
在CBV中使用:
# CBV中使用 from django.views import View from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator # CBV的csrf装饰器,只能加载类上(指定方法为dispatch)和dispatch方法上(django的bug) # 给get方法使用csrf_token检测 @method_decorator(csrf_exempt,name='dispatch') class Foo(View): def get(self,request): pass def post(self,request): pass