中间件 Middleware

  • 中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。

  • 每个中间件组件负责做一些特定的功能。例如,Django 包含一个中间件组件 AuthenticationMiddleware,它使用会话将用户与请求关联起来。

  • 中间件类:

    • 中间件类须继承自 django.utils.deprecation.MiddlewareMixin
    • 中间件类须实现下列五个方法中的一个或多个:
      • def process_request(self, request): 执行路由之前被调用,在每个请求上调用,返回None或HttpResponse对象
      • def process_view(self, request, callback, callback_args, callback_kwargs): 调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
      • def process_response(self, request, response): 所有响应返回浏览器 被调用,在每个请求上调用,返回HttpResponse对象
      • def process_exception(self, request, exception): 当处理过程中抛出异常时调用,返回一个HttpResponse对象
      • def process_template_response(self, request, response): 在视图函数执行完毕且试图返回的对象中包含render方法时被调用;该方法需要返回实现了render方法的响应对象
    • 注: 中间件中的大多数方法在返回None时表示忽略当前操作进入下一项事件,当返回HttpResponese对象时表示此请求结束,直接返回给客户端
  • 编写中间件类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # file : middleware/mymiddleware.py
    from django.http import HttpResponse
    from django.utils.deprecation import MiddlewareMixin

    class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
    print("中间件方法 process_request 被调用")

    def process_view(self, request, callback, callback_args, callback_kwargs):
    print("中间件方法 process_view 被调用")

    def process_response(self, request, response):
    print("中间件方法 process_response 被调用")
    return response
  • 注册中间件:

    1
    2
    3
    4
    # file : settings.py
    MIDDLEWARE = [
    ...
    ]
  • 中间件的执行过程

跨站请求伪造攻击 CSRF

  • 跨站请求伪造攻击

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

    • CSRF中间件和模板标签提供对跨站请求伪造简单易用的防护。
  • 作用:

    • 不让其它表单提交到此 Django 服务器
  • 防范步骤:

    1. settings.py中确认 MIDDLEWARE 中 django.middleware.csrf.CsrfViewMiddleware是否打开
    2. 模板中,form标签下添加如下标签
      1
      {% csrf_token %}
  • 如果某个视图不需要django进行csrf保护,可以用装饰器关闭对此视图的检查

1
2
3
4
5
from django.views.decorators.csrf import csrf_exempt

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