Django-中间件
什么是中间件
简单来说就是到达路由前必须经过的过程
中间件常用的作用
1.反爬(用户访问频率限制)
2.用户是否是合法用户
3.用户登录校验
4.各种涉及到网站全局的功能
Django中间件
Django默认配置了7个中间件,当然我们还可以自己定制相关的中间件
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.mymiddleware.myaabb.MyMiddle1',
'app01.mymiddleware.myaabb.MyMiddle2',
]
Django默认暴露了5个可以供可以自定制的方法(这5个方法都会在特定的条件下触发)
方法一
1.新建一个文件夹,里面键一个py文件
2.写一个类,注意要继承指定的类
from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
3.重写相关的方法,并且要去settings里面手动的配置,如上
具体方法
常用
process_request:请求来的时候 会从上往下依次经过每一个中间件里面process_request,一旦里面返回了HttpResponse对象那么就不再往后执行了,会执行同一级别的process_response
def process_request(self,request):
print('我是第一个自定义中间件里面的process_request方法')
return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值") # 直接原地返回
process_response:响应走的时候 会从下往上依次进过每一个中间件里面的process_response
def process_response(self,request,response): # response就是要返回给用户的数据
print("我是第一个自定义中间件里面的process_response方法")
return response
不常用,但是需要了解
process_view:路由匹配成功之后执行视图函数之前触发
process_exception:当视图函数出现异常(bug)的时候自动触发
process_template_response:当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发
csrf中间件
CSRF(Cross-site request forgery)跨站请求伪造,就类似钓鱼网站,比如你在假网站上转账,钱转走了,转去的账户却不对,这就是csrf中间件要解决的问题
最简单的原理
你写的form表单中,用户的用户名,密码都会真实的提交给银行后台
但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框
黑客提前写好了一个隐藏的带有name和value的input框
怎么解决钓鱼问题
主要思路就是确保,用户使用的网页是,官方服务区提供的而不是,盗版网站假冒的
解决钓鱼网站的策略
只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串
当用户提交post请求的时候 我会自动先取查找是否有该随机字符串
如果有 正常提交
如果没有 直接报403
实现方式
form提交
直接在form里面加一个
{% csrf_token %}
django会自动渲染一个随机字符串的input
ajax
1.自己再页面上先通过{% csrf_token %}获取到随机字符串 然后利用标签查找 data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
2.data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
3.直接在界面引入下面代码的js文件
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
个别验证csrf或者个别验证csrf
因为csrf是中间件,它的作用范围是全局,所以为了解决特殊的需求,需要一些特殊的方法
装饰器
csrf_exempt#被装饰的方法不校验
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
# 第一种
# @method_decorator(csrf_exempt,name='dispatch')
class MyCsrf(View):
# 第二种
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')
除了csrf_exempt之外 所有的其他装饰器 在CBV上面都有三种方式
csrf_protect#被装饰的方法校验
@method_decorator(csrf_protect,name='post')
class MyCsrf(View):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')
@method_decorator(csrf_protect)
def post(self,request):
return HttpResponse('post')