当前位置:首页>python>Python从入门到精通day50

Python从入门到精通day50

  • 2026-09-02 19:59:26
Python从入门到精通day50

中间件的应用:统一处理登录验证与请求拦截

在 Django 项目中,当多个功能需要统一的登录验证、权限检查等逻辑时,重复在视图函数中编写校验代码会导致代码冗余。中间件作为 Django 请求 / 响应的 “拦截过滤器”,能将这类通用逻辑抽离出来,实现代码复用和业务解耦。本文将详解 Django 中间件的核心概念、内置中间件作用,并通过实战演示如何自定义中间件实现登录验证。

一、Django 中间件核心概述

中间件是嵌入在 Web 应用请求 - 响应流程中的组件,可拦截、过滤、修改请求和响应,专注于完成通用横切功能(如登录验证、日志记录、CSRF 防护、会话管理等)。Django 框架本身就内置了多个核心中间件,通过组合不同中间件实现复杂的通用能力。

1. 内置中间件配置与作用

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

核心内置中间件详解

中间件类
核心作用
关键配置项
CommonMiddleware
基础请求处理
APPEND_SLASH
(URL 补/)、DISALLOWED_USER_AGENTS(禁用用户代理)
SecurityMiddleware
安全防护
SECURE_SSL_REDIRECT
(强制 HTTPS)、SECURE_BROWSER_XSS_FILTER(XSS 过滤)
SessionMiddleware
会话管理(为 request 绑定session对象)
SESSION_COOKIE_AGE
(会话有效期)、SESSION_ENGINE(会话存储引擎)
CsrfViewMiddleware
CSRF 防护
CSRF_COOKIE_SECURE
(HTTPS 下传输 CSRF 令牌)
XFrameOptionsMiddleware
防范点击劫持
X_FRAME_OPTIONS
(DENY/SAMEORIGIN)

2. 中间件执行顺序

  • • 请求阶段:中间件按MIDDLEWARE列表从上到下执行,完成拦截 / 处理后,请求才会进入 URL 解析和视图函数;
  • • 响应阶段:中间件按MIDDLEWARE列表从下到上执行,可对响应做最终修改后返回给用户;
  • • 拦截规则:若某中间件在请求阶段直接返回响应(如重定向、JSON 提示),后续中间件和视图函数将不再执行。

二、自定义中间件:统一登录验证

1. 需求场景

需对投票、导出 Excel、查看统计图表等功能做登录限制,避免在每个视图函数中重复编写session校验代码。

2. 中间件实现方式

Django 支持两种自定义中间件的方式:基于函数(推荐,接近装饰器写法)、基于类(旧版写法,兼容低版本 Django)。方式 1:基于函数的中间件(推荐)在项目根目录创建middlewares.py,编写登录验证中间件:

"""middlewares.py"""from django.http import JsonResponsefrom django.shortcuts import redirect# 需要登录才能访问的资源路径LOGIN_REQUIRED_URLS = {'/praise/', '/criticize/', '/excel/', '/teachers_data/'}defcheck_login_middleware(get_resp):defwrapper(request, *args, **kwargs):# 请求的资源路径在上面的集合中if request.path in LOGIN_REQUIRED_URLS:# 会话中包含userid则视为已经登录if'userid'notin request.session:# 判断是不是Ajax请求if request.is_ajax():# Ajax请求返回JSON数据提示用户登录return JsonResponse({'code': 10003, 'hint': '请先登录'})else:                    backurl = request.get_full_path()# 非Ajax请求直接重定向到登录页return redirect(f'/login/?backurl={backurl}')return get_resp(request, *args, **kwargs)return wrapper

方式 2:基于类的中间件(旧版兼容写法)适用于低版本 Django,需继承MiddlewareMixin,重写钩子函数:

from django.utils.deprecation import MiddlewareMixinclassMyMiddleware(MiddlewareMixin):defprocess_request(self, request):passdefprocess_view(self, request, view_func, view_args, view_kwargs):passdefprocess_template_response(self, request, response):passdefprocess_response(self, request, response):passdefprocess_exception(self, request, exception):pass

上面类中的五个方法都是中间件的钩子函数,分别在收到用户请求、进入视图函数之前、渲染模板、返回响应和出现异常的时候被回调。当然,写不写这些方法是根据中间件的需求来确定的,并不是所有的场景都需要重写五个方法,下面的图相信能够帮助大家理解这种写法。

3. 激活自定义中间件

修改settings.py的MIDDLEWARE列表,添加自定义中间件(注意顺序):

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','debug_toolbar.middleware.DebugToolbarMiddleware','vote.middlewares.check_login_middleware',]

4.关键注意事项

  1. 1. 中间件顺序:
    • • 登录验证中间件需放在SessionMiddleware之后(依赖request.session);
    • • 若中间件依赖其他内置中间件(如AuthenticationMiddleware),需保证被依赖的中间件在前;
  2. 2. URL 匹配优化:若需支持模糊匹配(如/api/*),可改用正则表达式:
import reLOGIN_REQUIRED_PATTERNS = [    re.compile(r'^/praise/'),    re.compile(r'^/excel/')]# 匹配逻辑ifany(pattern.match(request.path) for pattern in LOGIN_REQUIRED_PATTERNS):# 登录校验逻辑
  1. 3. 兼容 Ajax 请求:前端 Ajax 请求被拦截时,返回 JSON 而非重定向,避免前端解析异常;
  2. 4. 登录后回跳:重定向到登录页时携带backurl参数,登录成功后可通过该参数返回原页面:
# 登录视图函数示例deflogin(request):if request.method == 'POST':# 验证用户信息...# 登录成功后回跳        backurl = request.GET.get('backurl', '/')return redirect(backurl)return render(request, 'login.html')

三、中间件扩展场景

除登录验证外,中间件还可实现以下通用功能:

  1. 1. 接口限流:记录 IP 请求频率,限制高频访问;
  2. 2. 日志记录:统一记录所有请求的 URL、耗时、响应状态;
  3. 3. 跨域处理:添加 CORS 响应头,解决前端跨域问题;
  4. 4. 权限校验:基于用户角色拦截未授权请求;
  5. 5. 数据加密 / 解密:对请求 / 响应数据做加解密处理。示例:接口限流中间件
"""接口限流中间件:限制单IP每分钟最多请求60次"""import timefrom django.http import JsonResponsefrom collections import defaultdict# 存储IP请求记录:{ip: [请求时间1, 请求时间2, ...]}IP_REQUEST_RECORDS = defaultdict(list)defrate_limit_middleware(get_response):defmiddleware(request, *args, **kwargs):        client_ip = request.META.get('REMOTE_ADDR')        current_time = time.time()# 清理1分钟前的请求记录        IP_REQUEST_RECORDS[client_ip] = [t for t in IP_REQUEST_RECORDS[client_ip] if current_time - t < 60]# 检查请求频率iflen(IP_REQUEST_RECORDS[client_ip]) >= 60:return JsonResponse({'code': 10004, 'msg': '请求过于频繁,请1分钟后重试'})# 记录本次请求时间        IP_REQUEST_RECORDS[client_ip].append(current_time)return get_response(request, *args, **kwargs)return middleware

总结

  1. 1. 中间件是 Django 处理通用横切逻辑的核心组件,请求阶段从上到下执行,响应阶段从下到上执行,可拦截请求 / 修改响应;
  2. 2. 自定义中间件推荐使用函数式写法,需注意执行顺序(依赖 session 的中间件需放在SessionMiddleware之后);
  3. 3. 登录验证中间件可统一拦截未登录请求,区分 Ajax / 普通请求返回不同响应,避免视图函数代码冗余;
  4. 4. 中间件还可扩展实现接口限流、日志记录、跨域处理等通用功能,是 Django 项目解耦和复用的关键手段。

AI工具,提高学习,工作效率,神器

国内直接使用顶级AI工具

谷歌浏览器访问:

https://www.nezhasoft.cloud/r/vMPJZr

最新文章

随机文章