这篇文章主要介绍“Django中间件的应用场景是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Django中间件的应用场景是什么”文章能帮助大家解决问题。
中间件的应用
在之前的文章中,我们已经实现了用户必须登录才能投票的限制。然而,如果我们的应用中有很多功能都需要用户先登录才能执行,例如将前面导出Excel报表和查看统计图表的功能都做了必须登录才能访问的限制,那么我们是不是需要在每个视图函数中添加代码来检查session中是否包含
userid
的代码呢?答案是否定的,如果这样做了,我们的视图函数中必然会充斥着大量的重复代码。编程大师 Martin Fowler 曾经说过:代码有很多种坏味道,重复是最坏的一种。在 Python 程序中,我们可以通过装饰器来为函数提供额外的能力;在 Django 项目中,我们可以把类似于验证用户是否登录这样的重复性代码放到 中间件 中。Django中间件概述
中间件是安插在 Web 应用请求和响应过程之间的组件,它在整个 Web 应用中扮演了拦截过滤器的角色,通过中间件可以拦截请求和响应,并对请求和响应进行过滤(简单的说就是执行额外的处理)。通常,一个中间件组件只专注于完成一件特定的事,例如:Django 框架通过
SessionMiddleware
中间件实现了对 session 的支持,又通过 AuthenticationMiddleware
中间件实现了基于 session 的请求认证。通过把多个中间件组合在一起,我们可以完成更为复杂的任务,Django 框架就是这么做的。在 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',
]
我们稍微为大家解释一下这些中间件的作用:
CommonMiddleware
- 基础设置中间件,可以处理以下一些配置参数。-
- 不被允许的用户代理(浏览器)DISALLOWED_USER_AGENTS
-
- 是否追加APPEND_SLASH
/
-
- 浏览器缓存相关USE_ETAG
SecurityMiddleware
- 安全相关中间件,可以处理和安全相关的配置项。-
- 强制使用 HTTPS 的时间SECURE_HSTS_SECONDS
-
- HTTPS 是否覆盖子域名SECURE_HSTS_INCLUDE_SUBDOMAINS
-
- 是否允许浏览器推断内容类型SECURE_CONTENT_TYPE_NOSNIFF
-
- 是否启用跨站脚本攻击过滤器SECURE_BROWSER_XSS_FILTER
-
- 是否重定向到 HTTPS 连接SECURE_SSL_REDIRECT
-
- 免除重定向到 HTTPSSECURE_REDIRECT_EXEMPT
SessionMiddleware
- 会话中间件。
CsrfViewMiddleware
- 通过生成令牌,防范跨请求份伪的造中间件。
XFrameOptionsMiddleware
- 通过设置请求头参数,防范点击劫持攻击的中间件。在请求的过程中,上面的中间件会按照书写的顺序从上到下执行,然后是 URL 解析,最后请求才会来到视图函数;在响应的过程中,上面的中间件会按照书写的顺序从下到上执行,与请求时中间件执行的顺序正好相反。
自定义中间件
Django 中的中间件有两种实现方式:基于类的实现方式和基于函数的实现方式,后者更接近于装饰器的写法。装饰器实际上是代理模式的应用,将横切关注功能(与正常业务逻辑没有必然联系的功能,例如:身份认证、日志记录、编码转换之类的功能)置于代理中,由代理对象来完成被代理对象的行为并添加额外的功能。中间件对用户请求和响应进行拦截过滤并增加额外的处理,在这一点上它跟装饰器是完全一致的,所以基于函数的写法来实现中间件就跟装饰器的写法几乎一模一样。
下面我们用自定义的中间件来实现用户登录验证的功能。
我们可以自定义中间件来实现对登录状态的检查,如果用户未登录的话,就直接跳转到登录页面。下面是一个简单的中间件,用于检查用户是否登录:
"""
middlewares.py
"""
from django.http import JsonResponse
from django.shortcuts import redirect
# 需要登录才能访问的资源路径
LOGIN_REQUIRED_URLS = {'/praise/', '/criticize/', '/excel/', '/teachers_data/'}
def check_login_middleware(get_resp):
def wrapper(request, *args, **kwargs):
# 请求的资源路径在上面的集合中
if request.path in LOGIN_REQUIRED_URLS:
# 会话中包含 userid 则视为已经登录
if 'userid' in request.session:
return get_resp(request, *args, **kwargs)
# 跳转到登录页面
else:
return redirect('/login/')
return get_resp(request, *args, **kwargs)
return wrapper
然后,在项目的配置文件中,将中间件添加到
MIDDLEWARE
列表中即可:MIDDLEWARE = [
# ...
'path.to.check_login_middleware',
# ...
]
这样,我们就可以在需要登录才能访问的视图函数中添加一个装饰器,例如:
@check_login_middleware
def praise(request):
pass
这样就完成了对登录状态的检查。