飞道的博客

18. Django进阶:中间件

213人阅读  评论(0)

一、定义

  • 中间件是Django请求/响应处理的钩子框架。它是一个轻量级的、低级的"插件"系统,用于全局改变Django的输入或者输出
  • 中间件以类的形式体现
  • 每个中间件组件负责做一些特定的功能。例如:Django包含一个中间件组件AuthenticationMiddleware,它使用会话将用户与请求关联起来

二、中间件规则

中间件类必须继承自django.utils.deprecation.MiddlewareMixin

中间件类须实现下列五个方法中的一个或多个:

  1. process_request(self, request)

    执行路由之前被调用,在每个请求上调用,返回NodeHttpResponse对象

    返回Node说明请求可以继续往下走

    返回HttpResponse说明请求终止

  2. process_view(self, request, callback, callback_args, callback_kwargs)

    调用视图之前被调用,在每个请求上调用,返回NodeHttpResponse对象

  3. process_response(self, request, response)

    所有响应返回浏览器被调用,在每个请求上调用,返回HttpResponse对象

  4. process_exception(self, request, exception)

    当处理过程中抛出异常时调用,返回HttpResponse对象

    统一异常处理

  5. process_template_response(self, request, response)

    在视图函数执行完毕且试图返回的对象中包含render方法时被调用,该方法需要返回实现了render方法的响应对象

【注】中间件中大多数方法在返回None时表示忽略当前操作进入下一项事,当返回HttpResponse对象时表示此请求结束,直接返回给客户端

三、新建中间件

from django.utils.deprecation import MiddlewareMixin


class MyMW(MiddlewareMixin):

    def process_request(self, request):
        print("MyMW process_request..")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("MyMW process_view..")

    def process_response(self, request, response):
        print("MyMW process_response..")
        return response

四、注册中间件

setting.py中需要注册一下自定义的中间件

# file : setting.py
MIDDLEWARE = [
    ···
]

五、使用中间件

查看输出信息

六、中间件顺序

测试多个中间件

两个中间件

注册中间件

查看访问效果

注意:配置为数组,中间件被调用时,以’先上到下’’先下到上’的顺序调用

七、练习1

用中间件实现强制某个IP地址只能向/test开头的地址发送5次请求

提示:

  • request.META['REMOTE_ADDR']可以得到远程客户端的IP地址

  • request.path_info可以得到客户端访问的请求路由信息

7.1. 中间件

class VisitLimit(MiddlewareMixin):
    visit_times = {
   }

    def process_request(self, request):
        ip_address = request.META['REMOTE_ADDR']
        path_url = request.path_info
        if not re.match('^/test', path_url):
            return None
        times = self.visit_times.get(ip_address, 0)
        print('ip', ip_address, '已经访问', times, '次')
        self.visit_times[ip_address] = times + 1
        if times < 5:
            return None
        return HttpResponse('您已经访问过' + str(times) + '次,访问被禁止')

7.2. 注册

7.3. 测试

八、🧨🧨🧨中间件执行总流程

九、CSRF攻击

9.1. 定义

CSRF —— 跨站伪造请求攻击

某些恶意网站上包含链接、表单按钮或者JavaScript,他们会利用登录过的用户在浏览器中的认证信息试图在你的网站上完成某些操作。这就是跨站请求伪造(CSRF,即Cross-Site Request Forgey)

利用Cookies中保存了登录状态且自动提交

9.2. CSRF防范

  • django采用比对暗号机制防范攻击
  • Cookies中存储暗号1,模板中表单里藏着暗号2,用户只有在本网站下提交数据,暗号2才会随表单提交给服务器,django对比两个暗号,对比成功,则认为是合法请求,都则是违法请求—403响应码

9.3. 配置步骤

  1. setting.py中确认MIDDLEWAREdjango.middleware.csrf.CsrfViewMiddleware是否打开

  2. 模板中,form标签下添加如下标签

    {% csrf_token %}
    

9.4. 测试

9.4.1. 路由

from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('test_cache', views.test_cache),
    path('test_mw', views.test_mw),
    path('test_csrf', views.test_csrf),
]

9.4.2. 界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/test_csrf" method="post">
    <input type="text" name="username">
    <input type="submit" value="提交">
</form>
</body>
</html>

9.4.3. 配置

9.4.4. 视图函数

def test_csrf(request):
    if request.method == 'GET':
        return render(request, 'test_csrf.html')
    elif request.method == 'POST':
        return HttpResponse('test_csrf')

9.4.5. 不加标签

9.4.6. 加标签

cookies暗号

界面暗号

9.5. 特殊说明

如果某个视图不需要django进行csrf保护,可以用装饰器关闭对此视图的检查

样例:

from django.views.decorators.csrf import csrf_exempt


@csrf_exempt
def my_view(request):
	return HttpResponse('hello world')

转载:https://blog.csdn.net/KaiSarH/article/details/116718518
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场