chan

朝生暮死不足笑 但悲百年不足道

【Django】中间件middleware


Django 的 中间件(Middleware) 是一种在请求和响应处理过程中进行处理的钩子机制。它允许你在请求被视图处理之前或响应返回客户端之前进行修改或处理。通过中间件,Django 提供了一种优雅的方式来扩展应用程序的功能,比如处理请求和响应、进行身份验证、日志记录、缓存等。

1. 中间件的基本概念

中间件 是一个处理请求和响应的组件链。每个中间件都可以访问和修改请求对象(request)和响应对象(response)。中间件在 Django 的请求-响应周期中处于“请求”和“视图”之间,或“视图”和“响应”之间。

2. 中间件的工作原理

Django 中的中间件工作原理可以用以下几个步骤来概括:

  1. 请求进入中间件
    • 当用户发送一个请求时,Django 会按顺序依次通过每个中间件(从 MIDDLEWARE 设置中指定的中间件列表中)进行处理。每个中间件都有机会修改请求对象(request)。
  2. 请求传递给视图
    • 当请求通过所有的中间件之后,它会到达对应的视图函数。视图函数会处理请求并返回一个响应对象(response)。
  3. 响应返回给中间件
    • 当视图函数返回响应后,Django 会将响应对象通过所有的中间件链(与请求处理的顺序相反)传递回去。每个中间件可以修改响应对象,最终返回给客户端。

3. 中间件的工作流程

中间件的工作流程可以分为两个阶段:

  • 请求阶段
    • 当请求进入 Django 应用时,Django 会依次通过所有中间件(按 MIDDLEWARE 设置中的顺序)来处理请求。
    • 每个中间件可以:
      • 检查请求头、请求数据。
      • 修改请求对象(比如通过检查用户身份、修改请求内容等)。
      • 中间件可以选择终止请求,比如直接返回一个响应而不让视图继续执行(例如认证失败时直接返回 401 错误)。
  • 响应阶段
    • 当视图返回响应后,Django 会依次将响应对象传递给每个中间件(顺序与请求处理阶段相反)。
    • 每个中间件可以:
      • 修改响应对象(例如修改响应头、内容、缓存等)。
      • 最终将响应返回给客户端。

4. 中间件的结构

一个典型的中间件类在 Django 中是一个 Python 类,它至少需要实现以下两个方法:

  • __init__(self):用于初始化中间件实例,通常不会修改任何内容。
  • __call__(self, request)process_requestprocess_response 方法(具体依赖于中间件的实现方式)。

在 Django 1.10 之后,中间件的结构是基于类的,而不是函数:

  1. 类中间件
    • 从 Django 1.10 起,中间件以类的形式存在。中间件类需要实现以下两个方法:
      • __init__(self): 中间件的初始化方法(可以不做任何操作)。
      • __call__(self, request): 对每个请求的处理逻辑。
      • process_request(self, request):处理请求,在视图处理之前执行。
      • process_response(self, request, response):处理响应,在视图处理后执行。
    例如: class CustomMiddleware: def __init__(self, get_response): # get_response 是调用下一个中间件或视图的函数 self.get_response = get_response def __call__(self, request): # 在请求到达视图前执行的代码 print("请求到达中间件") # 调用下一个中间件或视图处理请求 response = self.get_response(request) # 在视图返回响应后执行的代码 print("响应返回到中间件") return response
  2. 函数中间件
    • 旧版本 Django 中(1.9 及以前),中间件是通过函数来实现的,每个中间件函数接收 requestresponse 对象。
    def custom_middleware(get_response): def middleware(request): # 在请求到达视图前执行的代码 print("请求到达中间件") # 调用下一个中间件或视图处理请求 response = get_response(request) # 在视图返回响应后执行的代码 print("响应返回到中间件") return response return middleware

5. 常见的中间件功能

以下是 Django 中常见的几种中间件功能,它们在很多应用中都有用:

(1) 身份验证

  • 中间件可以检查请求是否已经通过身份验证,例如用户是否登录。如果用户没有登录,可以将其重定向到登录页面。

(2) CSRF 防护

  • Django 内置了 CSRF 防护中间件,它通过检测请求中的 CSRF Token 来防止跨站请求伪造攻击。

(3) Session 管理

  • 中间件可以管理会话(session)。它会从请求中读取 sessionid cookie 来获取会话数据,并将其存储在 request.session 中。

(4) 缓存

  • 可以用中间件来缓存特定的视图响应或整个页面,以提高应用的性能。

(5) 安全性

  • 中间件可以帮助添加 HTTP 安全头,保护网站免受攻击(例如,X-Content-Type-OptionsX-Frame-Options 等)。

(6) 请求日志记录

  • 可以在中间件中记录每次请求的信息,如请求的 URL、请求时间、用户 IP 等。

(7) 跨域资源共享(CORS)

  • 允许你在中间件中处理 CORS 请求,控制哪些域可以访问你的资源。

6. 中间件的配置

在 Django 中,你需要在 settings.py 文件的 MIDDLEWARE 配置项中指定中间件列表。Django 会按这个列表中的顺序依次调用中间件。

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',
]

顺序的重要性

  • 中间件的顺序非常重要。在请求阶段,Django 会按 MIDDLEWARE 列表的顺序调用中间件。类似地,在响应阶段,Django 会按 相反的顺序 调用它们。
  • 比如,如果某个中间件负责身份验证,应该放在其他中间件之前。

7. 总结

  • 中间件 是在请求到达视图函数之前和响应返回客户端之前对请求和响应进行处理的钩子。
  • 它是 Django 的一个强大机制,用于实现功能扩展,如身份验证、日志记录、CSRF 防护、会话管理等。
  • 中间件以类或函数的形式存在,可以在多个请求中共享处理逻辑,提高代码的复用性和可维护性。
  • 配置和调用顺序非常重要,因为它会影响请求的处理顺序和响应的返回顺序。

通过合理使用中间件,可以让你的 Django 应用更加灵活和强大。

评论
还没有评论
    发表评论 说点什么