• Django请求生命周期及中间件介绍,结尾csrf


    django的请求生命周期

     django中的中间件:

     进入源码的方法:from django.middleware.secuity import SecurityMiddleware

    请求来时会依次执行每一个中间件里面的process_request方法,(如果没有直接通过)

    请求走时会依次执行每一个中间件里面的process_response方法,(如果没有直接通过)

    自定义中间件:在应用里新建一个任意的文件夹,在文件夹里新建一个任意的.py文件

     

    请求来了是从上往下一次执行七个中间件,在依次返回,如果我定义个中间件,

    在中间件里返回HttpResponse的话,那么我定义的中间件下面的中间件都不走了,直接从我的中间件开始依次返回。

    如果在process_request方法中返回HttpResponse的话,不会往下执行,会从同级别的Response方法开始依次返回

    必须将response接收到的数据返回,不然直接报错

    from django.utils.deprecation import MiddlewareMixin
    
    class MyMiddleware(MiddlewareMixin):
        def process_request(self,request):
            print('我是自定义的第一个中间件')
        def process_response(self,request,response):
            print('我是自定义中间件第一个Response方法')
    
    class MyMiddleware2(MiddlewareMixin):
        def process_request(self,request):
            print('我是自定义的第二个中间件')
        def process_response(self,request,response):
            print('我是自定义中间件第二个Response方法')
    
    # 结果
    #我是自定义的第一个中间件
    #我是自定义的第二个中间件
    #我是自定义中间件第二个Response方法
    #我是自定义中间件第一个Response方法

    中间件可以定义的五个方法:全局相关的功能时可以自定义中间件

    process_request(self,request)
    # 请求来的时候依次从上往下执行
    process_view(self, request, view_func, view_args, view_kwargs)
    # 路由匹配成功,即将要执行视图函数之前会自动触发
    # 如果返回了HttpResponse对象,那么会从下往上执行每一个中间件里的process_response
    process_template_response(self,request,response)
    # 当返回的对象有一个render()方法
    process_exception(self, request, exception)
    # 视图函数里有错误的时候自动触发,从下往上依次执行
    process_response(self, request, response)
    # 请求走的时候依次从下往上执行

     应用场景:

    1、做IP访问频率限制

    某些IP访问服务器的频率过高,进行拦截,比如限制每分钟不能超过20次。

    2、URL访问过滤

    如果用户访问的是login视图(放过)

    如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!

     

    怎么利用这个csrf呢

     在form表单中:

    <form action="" method="post">
        {% csrf_token %}
        <p>用户名:<input type="text" name="name"></p>
        <p>密码:<input type="text" name="password"></p>
        <p><input type="submit"></p>
    </form>

    在ajax中放入data里:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="/static/jquery-3.3.1.js"></script>
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post">
        {% csrf_token %}
        <p>用户名:<input type="text" name="name"></p>
        <p>密码:<input type="text" name="password" id="pwd"></p>
        <p><input type="submit"></p>
    </form>
    <button class="btn">点我</button>
    </body>
    <script>
        $(".btn").click(function () {
            $.ajax({
                url: '',
                type: 'post',
                data: {
                    'name': $('[name="name"]').val(),
                    'password': $("#pwd").val(),
                    'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
                },
                success: function (data) {
                    console.log(data)
                }
    
            })
        })
    </script>
    </html>

    全站禁用:注释掉中间件 'django.middleware.csrf.CsrfViewMiddleware',

    局部禁用:用装饰器(在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装饰器,只能加载类上(django的bug)
    # 给get方法使用csrf_token检测
    @method_decorator(csrf_exempt,name='get'),#不能直接放在函数上,可以放在分发函数dispatch上不需要指定名字,是什么请求就会分发到指定的函数上
    # 给post加
    @method_decorator(csrf_exempt,name='post')#
    # 给所有方法加
    @method_decorator(csrf_exempt,name='get')#
    class Foo(View):
        def get(self,request):#
            pass
        def post(self,request):#
            pass
  • 相关阅读:
    C#泛型使用小记
    Unity3d + NGUI 的多分辨率适配
    CodeSmith(1 生成实体)
    从数据库读取数据Table后转成对应的实体泛型方法
    安卓data./data没数据的时候
    Java工具
    SqlBulkCopy 用法
    Wind7 64位配置安卓环境
    .net和c#下的自定义配置
    Log4Net可以根据不同的类容输出到不同的文件夹下面
  • 原文地址:https://www.cnblogs.com/python-Arvin/p/11890556.html
Copyright © 2020-2023  润新知