Django-中间件

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')
原文地址:https://www.cnblogs.com/zx125/p/11768952.html