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加