深入理解 Django 的中间件 Middleware
Django 的中间件是一种可插拔的方式,可以处理用户请求和响应的过程,常用于处理日志、安全、缓存、权限等。本文介绍如何使用 Django 的中间件,并提供两个示例说明。
1. 中间件的基本结构
Django 中间件的基本结构包括了三个方法:
__init__(self, get_response)
:在中间件被初始化时执行,可用于对中间件进行设定。__call__(self, request)
:每次接受请求时都会执行,可用于处理请求前的逻辑。process_response(self, request, response)
:在视图响应后执行,可用于处理响应后的逻辑。
这三个方法中,只有 __call__
是必须实现的方法,其他两个方法是可选的。
下面看一个简单的中间件示例。
class SwapMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
request.url, request.path = request.path, request.url
response = self.get_response(request)
return response
上面代码中,定义了一个简单的中间件类 SwapMiddleware
。该中间件只有 __init__
和 __call__
两个方法。在 __init__
方法中,我们通过接收 get_response
参数来保存访问视图函数时的回调函数。而在 __call__
方法中,我们将 request 的 url 和 path 交换位置,并调用回调函数 self.get_response(request)
拿到响应。(该例子是将 request 中的 url 和 path 交换位置,纯属娱乐,开发中并不会使用)
2. 中间件的配置
Django 的中间件需要在 django.settings.py
文件中进行配置。中间件按照顺序依次执行,如果前面的中间件处理了请求,那么后面的中间件将不再执行处理逻辑。这点需结合中间件的定义来理解。一般而言,中间件配置有两个关键字:
MIDDLEWARE
:是一个中间件列表,最好指定顺序。MIDDLEWARE_CLASSES
:是一个中间件类路径列表,大多数 legacy 代码使用这个指令。
下面是一个完整的配置示例:
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 官方推荐的中间件顺序。
3. 示例一:处理请求头
假设我们的网站需要验证每个请求中是否有指定的请求头 Authorization
,并获取请求头的值作为当前用户的 token,那么我们可以编写一个自定义中间件来完成该功能。代码如下:
class TokenMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
authorization = request.META.get('HTTP_AUTHORIZATION')
request.token = authorization.split()[1] if authorization else None
response = self.get_response(request)
return response
上面这个自定义中间件的作用是通过 request.META
获取请求头 Authorization
,并从中获取值作为 token 存储在 request 对象中,便于后续的视图函数使用。
4. 示例二:限制访问频率
假设我们的网站需要限制用户访问频率,每秒钟只允许访问一次。那么我们可以编写一个自定义中间件来处理该功能。代码如下:
import time
class RateLimitMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.limits = {} # 记录各 IP 的上次访问时间
def __call__(self, request):
ip = self.get_client_ip(request)
now = time.time()
last_visit_time = self.limits.get(ip, 0)
if now - last_visit_time < 1:
return HttpResponseForbidden('您访问过于频繁,请稍后再试。')
self.limits[ip] = now
response = self.get_response(request)
return response
def get_client_ip(self, request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
上面代码中,自定义中间件 RateLimitMiddleware
记录了各个用户的最近一次访问时间,如果与当前时间的时间差小于 1 秒,则返回一个 403 Forbidden 的响应即可。
值得注意的是,这个方法获取 IP 的方式,因网络架构的不同,可能无法获取到用户真实 IP。但是我们可以通过 Nginx 的 proxy_set_header
指令来弥补,具体可参考资料。
5. 总结
本文简单介绍了 Django 中间件的基本结构和配置方法,并提供了两个常用的示例说明,分别用于处理请求头和限制访问频率。中间件是 Django 一种强大的可插拔机制,可以用于丰富项目功能,并提高代码的可读性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Django的中间件middleware - Python技术站