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
原文地址:https://www.cnblogs.com/python-Arvin/p/11890556.html