Django-中间件
什么是中间件
简单来说就是到达路由前必须经过的过程

中间件常用的作用
1.反爬(用户访问频率限制)
2.用户是否是合法用户
3.用户登录校验
4.各种涉及到网站全局的功能
Django中间件
Django默认配置了7个中间件,当然我们还可以自己定制相关的中间件
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.mymiddleware.myaabb.MyMiddle1', 'app01.mymiddleware.myaabb.MyMiddle2', ]
Django默认暴露了5个可以供可以自定制的方法(这5个方法都会在特定的条件下触发)
方法一
1.新建一个文件夹,里面键一个py文件 2.写一个类,注意要继承指定的类 from django.utils.deprecation import MiddlewareMixin class MyMiddle(MiddlewareMixin): 3.重写相关的方法,并且要去settings里面手动的配置,如上
具体方法
常用 process_request:请求来的时候 会从上往下依次经过每一个中间件里面process_request,一旦里面返回了HttpResponse对象那么就不再往后执行了,会执行同一级别的process_response def process_request(self,request): print('我是第一个自定义中间件里面的process_request方法') return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值") # 直接原地返回 process_response:响应走的时候 会从下往上依次进过每一个中间件里面的process_response def process_response(self,request,response): # response就是要返回给用户的数据 print("我是第一个自定义中间件里面的process_response方法") return response 不常用,但是需要了解 process_view:路由匹配成功之后执行视图函数之前触发 process_exception:当视图函数出现异常(bug)的时候自动触发 process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发
csrf中间件
CSRF(Cross-site request forgery)跨站请求伪造,就类似钓鱼网站,比如你在假网站上转账,钱转走了,转去的账户却不对,这就是csrf中间件要解决的问题
最简单的原理
你写的form表单中,用户的用户名,密码都会真实的提交给银行后台
但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框
黑客提前写好了一个隐藏的带有name和value的input框
怎么解决钓鱼问题
主要思路就是确保,用户使用的网页是,官方服务区提供的而不是,盗版网站假冒的
解决钓鱼网站的策略
只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串
当用户提交post请求的时候 我会自动先取查找是否有该随机字符串
如果有 正常提交
如果没有 直接报403
实现方式
form提交
直接在form里面加一个 {% csrf_token %} django会自动渲染一个随机字符串的input
ajax
1.自己再页面上先通过{% csrf_token %}获取到随机字符串 然后利用标签查找 data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()}, 2.data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}, 3.直接在界面引入下面代码的js文件 function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('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); } } });
个别验证csrf或者个别验证csrf
因为csrf是中间件,它的作用范围是全局,所以为了解决特殊的需求,需要一些特殊的方法
装饰器 csrf_exempt#被装饰的方法不校验 from django.views.decorators.csrf import csrf_exempt, csrf_protect from django.utils.decorators import method_decorator # 第一种 # @method_decorator(csrf_exempt,name='dispatch') class MyCsrf(View): # 第二种 @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args,**kwargs) def get(self,request): return HttpResponse('hahaha') 除了csrf_exempt之外 所有的其他装饰器 在CBV上面都有三种方式 csrf_protect#被装饰的方法校验 @method_decorator(csrf_protect,name='post') class MyCsrf(View): @method_decorator(csrf_protect) def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args,**kwargs) def get(self,request): return HttpResponse('hahaha') @method_decorator(csrf_protect) def post(self,request): return HttpResponse('post')