Django 中间件机制详解与实战应用
中间件概述
Django 中间件是处理请求(request)和响应(response)之间逻辑的钩子框架,它允许你在视图函数执行前后插入自定义处理逻辑。中间件以全局方式作用于整个项目,因此在提升功能灵活性的同时,也需注意其对系统性能的影响。
默认中间件配置
在 Django 项目的 settings.py 文件中,默认启用了多个中间件:
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',
]
- SecurityMiddleware:提供安全防护,如强制 HTTPS、设置安全响应头。
- SessionMiddleware:启用会话支持。
- CommonMiddleware:处理常见 HTTP 行为,如 URL 规范化。
- CsrfViewMiddleware:防止跨站请求伪造攻击。
- AuthenticationMiddleware:将用户绑定到请求对象。
- MessageMiddleware:支持一次性消息传递。
- XFrameOptionsMiddleware:防止页面被嵌入 iframe,抵御点击劫持。
中间件核心方法
Django 中间件包含四个可选方法,按执行顺序如下:
process_request(request)process_view(request, view_func, view_args, view_kwargs)process_exception(request, exception)process_response(request, response)
1. process_request 与 process_response
这两个方法分别在请求进入和响应返回时触发。
process_request接收 request 对象,无返回值或返回 HttpResponse 对象。process_response必须返回一个 response 对象,通常原样返回或修改后返回。
示例代码
创建两个自定义中间件类:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class AuthCheckMiddleware(MiddlewareMixin):
def process_request(self, request):
print("认证检查中间件 - 请求开始")
def process_response(self, request, response):
print("认证检查中间件 - 响应结束")
return response
class LoggingMiddleware(MiddlewareMixin):
def process_request(self, request):
print("日志记录中间件 - 请求捕获")
def process_response(self, request, response):
print("日志记录中间件 - 响应发送")
return response
注册中间件(在 settings.py 中):
MIDDLEWARE += [
'myapp.middleware.AuthCheckMiddleware',
'myapp.middleware.LoggingMiddleware',
]
输出结果:
认证检查中间件 - 请求开始 日志记录中间件 - 请求捕获 [视图函数执行] 日志记录中间件 - 响应发送 认证检查中间件 - 响应结束
说明:请求阶段从上到下依次执行,响应阶段则逆序执行。
2. process_view
该方法在确定要调用哪个视图函数之后、实际调用之前执行。
def process_view(self, request, view_func, view_args, view_kwargs)
view_func:即将执行的视图函数。view_args/view_kwargs:传递给视图的位置参数和关键字参数。
使用场景示例
class ViewMonitorMiddleware(MiddlewareMixin):
def process_view(self, request, view_func, view_args, view_kwargs):
print(f"准备执行视图: {view_func.__name__}")
# 可在此处实现权限判断、API 调用统计等
若 process_view 返回 HttpResponse,则跳过后续所有 process_view 和视图函数,直接进入 response 阶段。
3. process_exception
仅在视图抛出异常时调用:
def process_exception(self, request, exception):
print(f"捕获异常: {exception}")
return HttpResponse("服务器内部错误", status=500)
此方法可用于统一异常处理、日志记录、错误页面展示等。
自定义中间件实现登录拦截
以下中间件实现免登录路径放行与未登录跳转:
class LoginRequiredMiddleware(MiddlewareMixin):
def process_request(self, request):
allowed_paths = ['/login/', '/register/', '/static/']
if any(request.path.startswith(path) for path in allowed_paths):
return None # 放行
if not request.user.is_authenticated:
return HttpResponse("请先登录", status=401)
return None # 继续处理
增强安全性:CORS 与安全头设置
通过中间件统一设置安全响应头:
class SecurityHeaderMiddleware(MiddlewareMixin):
def process_response(self, request, response):
# CORS 设置
response['Access-Control-Allow-Origin'] = 'https://trusted-site.com'
response['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
# 安全头
response['X-Content-Type-Options'] = 'nosniff'
response['X-Frame-Options'] = 'DENY'
response['X-XSS-Protection'] = '1; mode=block'
response['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
response['Referrer-Policy'] = 'strict-origin-when-cross-origin'
response['Content-Security-Policy'] = "default-src 'self'; script-src 'self'"
return response
执行流程图解
中间件执行遵循"洋葱模型":
- 请求进入 → 执行各中间件的
process_request(顺序执行) - → 执行
process_view(顺序执行) - → 调用视图函数
- → 视图返回或抛出异常
- → 若异常 → 执行
process_exception(逆序) - → 执行
process_response(逆序) - → 返回客户端
注意事项
- 中间件顺序影响执行逻辑,应合理排列。
- 避免在中间件中进行耗时操作,以免阻塞请求。
- 返回 HttpResponse 会中断后续中间件和视图执行。
- 生产环境建议关闭调试信息输出。