Django中间件
一、CBV加装饰器的三种方式
1、在类上面加,需要通过name参数指定被装饰的方法
2、直接在装饰方法上
3、重写dispatch方法,直接给dispatch装(该类中所有的方法都被装饰)
from django.shortcuts import render, HttpResponse, redirect from django.views import View from django.utils.decorators import method_decorator # 给CBV加装饰器 def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if username == 'jason' and password == '123': request.session['username'] = 'jason' return redirect('/home/') return render(request, 'login.html') from functools import wraps def login_auth(func): @wraps(func) def inner(request, *args, **kwargs): if request.session.get('name'): return func(request, *args, **kwargs) return redirect('/login/') return inner @method_decorator(login_auth, name='get') # ②给CBV加装饰器的第二种方式,name参数必须指定 class MyHome(View): @method_decorator(login_auth) # ③给CBV加装饰器的第三种方式。get、post方法都会被装饰 def dispatch(self, request, *args, **kwargs): super().dispatch(request, *args, **kwargs) @method_decorator(login_auth) # ①给CBV加装饰器的第一种方式 def get(self, request): return HttpResponse('get') def post(self, request): return HttpResponse('post')
二、django中间件
django请求生命周期
1、默认中间件
django默认有七个中间件,但是django暴露给用户可以自定义中间件并且里面可以写五种方法
重要: 1.请求来的时候会依次执行每一个中间件里面的process_request方法(如果没有直接通过) 2.响应走的时候会依次执行每一个中间件里面的process_response方法(如果没有直接通过) django中间件能够帮我实现 网站全局的身份验证,黑名单,白名单,访问频率限制,反爬相关:django用来帮你全局相关的功能校验
2、中间件的五种方法
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class MyMiddleware(MiddlewareMixin): def process_request(self, request): print('我是第一个自定义中间件里面的process_request方法') # return HttpResponse('哈哈') 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方法') print(view_func.__name__, view_func) # return HttpResponse('hello') def process_exception(self,request,exception): print('我是第一个自定义中间件里面的process_exception方法') print(exception) def process_template_response(self,request,response): print('我是第一个自定义中间件里面的process_template_response方法') return response class MyMiddleware1(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方法') print(view_func.__name__, view_func) def process_exception(self,request,exception): print('我是第二个自定义中间件里面的process_exception方法') print(exception) def process_template_response(self,request,response): print('我是第二个自定义中间件里面的process_template_response方法') return response
自定义中间件:
①新建一个任意名字的文件夹(如:mymiddleware),里面新建一个任意名字py文件(如:md) ②导入模块:from django.utils.deprecation import MiddlewareMixin
③在settings里配置:
'应用名.文件夹名.文件名.类名'
如:app01.mymiddleware.md.MyMiddleware
①process_request:请求来的时候从上往下依次执行每一个中间件里面的process_request
②process_response:响应走的时候会从下往上依次执行每一个中间件里面的process_response方法
③process_view:路由匹配成功执行视图之前自动触发(从上往下依次执行)
④process_exception:当视图函数报错了,自动触发(从下往上依次执行)
⑤process_template_response:视图函数返回的对象有一个render()方法,(从下往上依次执行)
三、csrf跨站请求伪造
csrf:跨站请求伪造。举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果
某个用户已经登录到你的网站上了,那么当这个用户点击这个恶意网站上的那个链接时,就会向你的网站发来一个请求,
你的网站会以为这个请求是用户自己发来的,其实呢,这个请求是那个恶意网站伪造的。
避免:第一步:django第一次响应来自某个客户端的请求时,后端随机产生一个token值,把这个token保存在SESSION状态中;同时,后端把这个token放到cookie中交给前端页面;
第二步:下次前端需要发起请求(比如发帖)的时候把这个token值加入到请求数据或者头信息中,一起传给后端;Cookies:{csrftoken:xxxxx}
第三步:后端校验前端请求带过来的token和SESSION里的token是否一致。
解决:要启用 django.middleware.csrf.CsrfViewMiddleware 这个中间件
再次,在所有的 POST 表单元素时,需要加上一个 {% csrf_token %}
xss:跨站脚本攻击。Web攻击中最常见的攻击方法之一,
它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的,
形成了一次有效XSS攻击,一旦攻击成功,它可以获取用户的联系人列表,
然后向联系人发送虚假诈骗信息,可以删除用户的日志等等,
有时候还和其他攻击方式同时实 施比如SQL注入攻击服务器和数据库、Click劫持、
相对链接劫持等实施钓鱼,它带来的危害是巨 大的,是web安全的头号大敌。
解决:一种方法是在表单提交或者url参数传递前,对需要的参数进行过滤,请看如下XSS过滤工具类代码
过滤用户输入的 检查用户输入的内容中是否有非法内容
def transfer(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 render(request, 'transfer.html') from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_exempt # 装饰的函数不进行中间件中csrf校验 def index1(request): return HttpResponse('ok') @csrf_protect # 装饰的函数进行中间件中csrf校验,即使注释也会报403错误 def index2(request): return HttpResponse('ok')
<form action="/index2/" 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>
1、跨站强求伪造
<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>
2、是否校验csrf
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')
3、csrf装饰CBV需要注意(******)
①csrf_protect:三种方式(跟正常的CBV装饰器一样)
from django.utils.decorators import method_decorator # 导入装饰器模块 @method_decorator(csrf_protect, name='post') # ②csrf装饰CBV,方法二(指定name) class Index3(View): @method_decorator(csrf_protect) # ③csrf装饰CBV,方法二(装饰所有的) def dispatch(self, request, *args, **kwargs): super().dispatch(request, *args, **kwargs) def get(self,request): return HttpResponse('get') @method_decorator(csrf_protect) # ①csrf装饰CBV,方法一 def post(self,request): return HttpResponse('post')
②csrf_exempt:只能有下面两种方式(其实都是给dispatch加)
from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') # 第一种 class Index3(View): @method_decorator(csrf_exempt) # 第二种 def dispatch(self, request, *args, **kwargs): super().dispatch(request, *args, **kwargs) def get(self,request): return HttpResponse('get') def post(self,request): return HttpResponse('post')