django中间件

django请求周期:

django 里中间件的源码查看小技巧:

from django.middleware.security import SecurityMiddleware 即用from 和 import 隔开即可

例:在SecurityMiddleware内部可以查看到三个方法
def __init__(self, get_response=None):
def process_request(self, request):
def process_response(self, request, response):

django默认有七个中间件,但是django暴露给用户可以自定义中间件并且里面可以写五种方法

1.请求来的时候会依次执行每一个中间件里面的process_request方法(如果没有直接通过)
2.响应走的时候会依次执行每一个中间件里面的process_response方法(如果没有直接通过)

django自定义中间件的执行流程:

1、process_request 的执行流程:
当有请求过来时,在中间件中,从上往下依次执行,
需要注意,当process_request里存在返回Httpresponse对象时,会立即返回,不会再执行下面的中间件了

 图示如下:

2、process_response 执行流程:

当有请求走时,在中间件值,从下往上依次执行
需要注意,当process_request里存在返回Httpresponse对象时,从自身的process_response开始依次往上执行,不执行下面的
图示如下:

3、process_view:路由匹配成功,执行视图之前,自动触发(从上往下依次执行)
需要注意,当process_view里存在返回Httpresponse对象时,不会继续往下走了,process_request和process_response
会正常按自身的流程执行
图示如下:

4、process_exception:当视图函数报错了,自动触发(从下往上依次执行)

 5、

process_template_response:视图函数返回的对象有一个render()方法
(或者表明该对象是一个TemplateResponse对象或等价方法)(从下往上依次执行)

上述相关的代码:

自定义的一个文件夹下的文件,需要将自定义的中间件在settings里注册

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.MymMddleware.text.MyTest1',
    'app01.MymMddleware.text.MyTest2',
]


test.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,render,redirect


class MyTest1(MiddlewareMixin):
    def process_request(self,request):
        print('第一个自定义的process_request方法')
        # return HttpResponse('我是michael')

    def process_response(self,request,response):
        print('第一个自定义的process_response方法')
        return response

    def process_view(self,request,view_func,view_args,view_kwargs):
        print('第一个自定义的process_view方法')
        # return HttpResponse('asdfghj')

    def process_exception(self,request,exception):
        print('第一个自定义的process_exception方法')

    def process_template_response(self,request,response):
        print('第一个自定义的process_template_response方法')



class MyTest2(MiddlewareMixin):
    def process_request(self,request):
        print('第二个自定义的process_request方法')

    def process_response(self,request,response):
        print('第二个自定义的process_response方法')
        return response
    def process_view(self,request,view_func,view_args,view_kwargs):
        print('第二个自定义的process_view方法')

    def process_exception(self,request,exception):
        print('第二个自定义的process_exception方法')

    def process_template_response(self,request,response):
        print('第二个自定义的process_template_response方法')


views.py

def test1(request):
    print('我是视图函数1')
    # nasmdasdas
    return HttpResponse('ok1')


def test2(request):
    print('我是视图函数2')
    return HttpResponse('ok2')

  

钓鱼网站小案例:

原始银行页面:

<body>
<h1>正经的网站</h1>
<form action="" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>money:<input type="text" name="money"></p>
    <p>others:<input type="text"  name="others"></p>
    <input type="submit">
</form>
</body>


def bank(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        money = request.POST.get('money')
        others = request.POST.get('others')
        print('%s向%s转了%s元' % (username, others, money))
        return HttpResponse('ok2')
    return render(request,'bank.html')

钓鱼网站页面:
<body>
<h1>钓鱼网站</h1>
<form action="http://127.0.0.1:8000/bank/" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>money:<input type="text" name="money"></p>
    <p>others<input type="text"></p>
    <input type="hidden" name="others" value="michael">
    <input type="submit"></form>
</body>


注意:
1、钓鱼网站提交的路径应该是银行后端对应的路径
2、应该开设两个django项目,注意将端口改变一下

原理:在钓鱼网站的html页面,隐藏需要的字段,给其value附上默认值,在发给银行后端完成相应操作

  

为了避免类似情况的发生,django中间件中存在  一个中间件可以帮我们处理这种情况的发生

django.middleware.csrf.CsrfViewMiddleware
我们只需要在提交数据时,加上{% csrf_token %} 即可

csrf跨站请求伪造:

django中间件能够帮我实现 网站全局的身份验证,黑名单,白名单,访问频率限制,反爬相关

form表单中如何跨站请求伪造
{% csrf_token %}
<input type="hidden" name="csrfmiddlewaretoken" value="2vzoo1lmSWgLTdI2rBQ4PTptJQKRQTRwnqeWRGcpdAQGagRp8yKg8RX2PdkF4aqh">
ps:value是动态生成的,每一次刷新都不一样

<form action="" method="post">{% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>money:<input type="text" name="money"></p>
    <p>others:<input type="text"  name="others"></p>
    <input type="submit">
</form

 

django-ajax 发送POST请求(csrf跨站请求的三种方式)

第一种:
<script>
  $(".eq").on("click",function () {
        $.ajax({
            url:"/eq/",
            type:"POST",
            data:{
                csrfmiddlewaretoken:{{ csrf_token }}, //必须写在模板中,才会被渲染
                a:$(".a").val(),
                b:$(".b").val()
            },
            success:function (data) {

              $(".c").html(data);
            }
        })
    })
</script>
第二种:
//模板页面中必须要有 {% csrf_token %}
<script>
    $(".eq").on("click",function () {
        $.ajax({
            url:"/eq/",
            type:"POST",
            data:{
                csrfmiddlewaretoken:$("input:first").val(),
                a:$(".a").val(),
                b:$(".b").val()
            },
            success:function (data) {

              $(".c").html(data);
            }
        })
    })
</script>
第三种:
<script src="/static/jquery.cookie.js"></script> //必须先引入它
<script>
    $("#btn").on("click",function () {
     $.ajax({
        url:"/lianxi/",
        type:"POST",
        headers:{"X-CSRFToken":$.cookie('csrftoken')},
        data:$("#f1").serialize()
    }
    )
    })

</script>

 

csrf 给 cbv 和 fbv 的全局校验

from django.views.decorators.csrf import csrf_exempt,csrf_protect
	@csrf_exempt  # 不校验csrf
	def index1(request):
		return HttpResponse('ok')

	@csrf_protect  # 校验csrf
	def index2(request):
		return HttpResponse('ok')
	
	
	csrf装饰CBV需要注意(******)
	csrf_protect 跟正常的CBV装饰器一样      三种
	csrf_exempt  只能有下面两种方式
			@method_decorator(csrf_exempt,name='dispatch')  # 第一种 
			class Index3(View):
				# @method_decorator(csrf_exempt)   # 第二种  
				def dispatch(self, request, *args, **kwargs):
					super().dispatch(request,*args,**kwargs)  
			其实都是给dispatch加

  

 

  

原文地址:https://www.cnblogs.com/changwenjun-666/p/11047740.html