返回Django 组件
一、中间件
1.1 什么是中间件?
(1) Django默认自带7个中间件,中间件类似于django的门卫,数据在进入和离开时都需要经过中间件
(2) 那么中间件能干什么?
控制用户访问频率,全局登录校验,用户访问白名单,黑名单等
(3) settings.py里面的中间件配置信息:
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',
]
(4) 中间件的执行规则:
1> 数据传到后端时:按照(3)中的顺序,从上到下,依次经过这些中间件处理
2> 当后端处理完之后,按照从下往上的执行顺序,经过这些中间件的处理之后传到前端
3> 还有一些规则,会在下面的代码中讲
(5) 中间件中主要有几个方法:
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
1.2 怎么自定义中间件?
(1) 先导包(单独的py文件)
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
(2) 自定义中间件
class Md1(MiddlewareMixin):
def process_request(self,request):
print("Md1请求")
def process_response(self,request,response):
print("Md1返回")
return response
class Md2(MiddlewareMixin):
def process_request(self,request):
print("Md2请求")
#return HttpResponse("Md2中断")
def process_response(self,request,response):
print("Md2返回")
return response
(3) 在view中定义一个视图函数
def index(request):
print("view函数...")
return HttpResponse("OK")
(4) 在settings.py中的MIDDLEWARE里注册自定义中间件
ps:执行结果
Md1请求
Md2请求
view函数...
Md2返回
Md1返回
ps2:如果当请求到达请求2的时候直接不符合条件返回,即return HttpResponse("Md2中断"),程序将把请求直接发给中间件2返回,然后依次返回到请求者,结果如下:
返回Md2中断的页面,后台打印如下:
Md1请求
Md2请求
Md2返回
Md1返回
总结:
(1) 中间件的process_request方法是在执行视图函数之前执行的。
(2) 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
(3) 不同中间件之间传递的request都是同一个对象。
多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,
---> 第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,
最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行。
二、csrf(跨站请求伪造)
2.1 举个栗子🌰:
钓鱼网站:银行转账的路径,可以拿到,然后你做一个跟银行一模一样的页面,也朝银行的接口提交数据,当用户在钓鱼网站输入对方账户名和转账金额之后,点击发送。其实内部是将对方账户换成了钓鱼网站的造假人员的账户,造成你转账转错账户的情况。
2.2 如何设置csrf_token
(1) 在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>
(2) Ajax中应用
<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>
2.3 csrf_token使用范围
# 只想给某个视图函数加上csrf校验
from django.views.decorators.csrf import csrf_exempt,csrf_protect
# 局部禁用
@csrf_exempt
def index(request):
pass
# 局部使用
@csrf_protect
def login(request):
pass
# CBV比较特殊,不能单独加在某个方法上
# 只能加在类上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@method_decorator(csrf_exempt,name='dispatch') # 第一种
class Csrf_Token(View):
@method_decorator(csrf_exempt) # 第二种
def dispatch(self,request,*args,**kwargs):
res = super().dispatch(request,*args,**kwargs)
return res
@method_decorator(csrf_exempt) # 这里这么写不行!!!
def get(self,request):
pass
def post(self,request):
pass