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')
views.py
<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>
transfer.html

 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')

 

 

posted @ 2019-06-18 17:30  TianShu  Views(367)  Comments(0Edit  收藏  举报