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加