django 3.2.13
一、中间件
原理:详细过程请阅读本专栏的第二篇Python Django源码运行过程的一、3.中间件的执行
中间件函数:
- process_request():完成请求对象的创建,但用户访问的网址尚未与网站的路由地址匹配。
- process_view():完成用户访问的网址与路由地址的匹配,但尚未执行视图函数。
- process_exception():在执行视图函数的期间发生异常,比如代码异常,主动抛出404异常等。
- process_response():完成视图函数的执行,但尚未将响应内容返回浏览器
- process_template_response():默认不执行,在视图函数完成操作后调用,除非视图函数返回的response中有render方法(几乎不会用,可以忽略)
默认启用的中间件:
文档:中文官方文档
1. 自带中间件
1.1 django.middleware.security.SecurityMiddleware
注意:下面说了大部分的参数,如果要全面请查看官方文档
配置参数(应用于setting.py):
1.1.1 强制内容转义
SECURE_CONTENT_TYPE_NOSNIFF # 默认为True
:设置回复的header为X-Content-Type-Options: nosniff
(避免浏览器根据内容猜测并且覆盖Content-Type,使得用户上传的恶意代码被运行)
1.1.2 HTTP 严格传输安全
解释: HTTP 严格传输安全:要求浏览器遇到该表头内容的,必须使用https方法,拒绝http请求该网站
SECURE_HSTS_SECONDS # 默认为False,其负责设置max-age(单位为秒)
:其应用于HTTP 严格传输安全,设置回复的header为Strict-Transport-Security:max-age=2592000
(当设置SECURE_HSTS_SECONDS
时才会启用该表头)SECURE_HSTS_INCLUDE_SUBDOMAINS #默认为False
:前提要设置SECURE_HSTS_SECONDS
,其应用于HTTP 严格传输安全,设置回复的header为Strict-Transport-Security:max-age=2592000;includeSubDomains
表示所有子域都遵守该规定SECURE_HSTS_PRELOAD# 默认为False
:前提要设置SECURE_HSTS_SECONDS
,其应用于HTTP 严格传输安全,设置回复的header为Strict-Transport-Security:max-age=2592000;includeSubDomains;preload
表示希望将你的网站提交到 浏览器预加载列表(需要单独填表格申请)
1.1.3 referrer反馈设置
解释: referrer-policy:头设置,该内容主要是用来设置请求referrer 请求头(是否发送完整的请求,不发送,还是主发送主域名),默认为same-origin
SECURE_REFERRER_POLICY
:用来设置referrer-policy
1.2 django.contrib.sessions.middleware.SessionMiddleware
原理:
process_request()
方法生成SessionStore实例,并赋给request.session, sever可以通过请求中传入的session_key,获得session内容,或者进行赋值,并且保存到session_cache 缓存中。process_response()
主要是为第一次请求生成session_key, 并且将session_cache 缓存中的内容进行持久化存储。
配置参数(应用于setting.py):
-
SESSION_COOKIE_AGE
默认: 1209600 (2 周,以秒为单位),会话 cookie 的寿命,以秒为单位 -
SESSION_COOKIE_HTTPONLY
默认: True,是否对会话 cookie 使用 HttpOnly 标志。如果设置为 True,客户端的 JavaScript 将无法访问会话 cookie -
SESSION_COOKIE_NAME
默认: ‘sessionid’,用于会话的 cookie 的名称。这可以是任何你想要的(只要它与你的应用程序中的其他 cookie 名称不同) -
SESSION_COOKIE_SECURE
默认:False,是否对会话 cookie 使用安全 cookie。如果设置为 True,cookie 将被标记为“安全”,这意味着浏览器可以确保 cookie 只在 HTTPS 连接下发送。
关闭这个配置并不是一个好主意,因为攻击者可以用数据包嗅探器捕获一个未加密的会话 cookie,并使用 cookie 来劫持用户的会话 -
SESSION_ENGINE
默认: ‘django.contrib.sessions.backends.db’
控制 Django 存储会话数据的地方。包括的引擎有:django.contrib.sessions.backends.db #数据库
- 这是Django默认的配置,SESSION_ENGINE已经配置好了因此无需修改,除此之外,你需要在INSTALLED APPS中注册django.contrib.sessions,然后migrate以生产数据表
django.contrib.sessions.backends.file #文件
- 同时需要设置SESSION_FILE_PATH参数,用以给出session data的文件目录。它的默认值为None,如果设置为None,那么Django将使用Python的标准临时文件模块去存储(默认是tempfile.gettempdir())
django.contrib.sessions.backends.cache #缓存
- 要想使用Django’s cache system来保存session data,需要先确保你正确配置了cache
django.contrib.sessions.backends.cached_db #缓存加数据库双重
- 在存储数据的时候,会将数据先存到缓存中,再存到数据库中。这样就可以保证万一缓存系统出现问题,session数据也不会丢失。在获取数据的时候,会先从缓存中获取,如果缓存中没有,那么就会从数据库中获取
django.contrib.sessions.backends.signed_cookies # session加密写到cookie
- 基于cookie的session,所有数据都保存在cookie中,一般情况下不建议使用这种方式
-
ESSION_FILE_PATH
默认: None,如果你使用的是基于文件的会话存储,那么这个选项设置了 Django 存储会话数据的目录,当使用默认值(None)时,Django 将使用系统的标准临时目录
1.3 django.middleware.common.CommonMiddleware
解释:可以禁止某些User-Agent,改写url,不如127.0.0.1/a
自动补充为127.0.0.1/a/
等等
1.4 django.middleware.csrf.CsrfViewMiddleware
解释:通过在 POST 表单中添加隐藏的表单字段,并检查请求的正确值,增加对跨站点伪造请求的保护
1.5 django.contrib.auth.middleware.AuthenticationMiddleware
解释:
配置参数(应用于setting.py):
AUTHENTICATION_BACKENDS
默认: [‘django.contrib.auth.backends.ModelBackend’],当试图认证用户时,要使用的认证后端类(字符串)列表AUTH_USER_MODEL
默认: ‘auth.User’,用来表示用户的模型PASSWORD_RESET_TIMEOUT
默认: 259200 (3 天,以秒为单位)密码重置链接的有效秒数。PASSWORD_HASHERS
Django加密密码的方法,有四种默认
1.6 django.contrib.messages.middleware.MessageMiddleware
解释:类似于flask的flash,使用场景:比如用户登录,然后通过后端模板进行一个信息反馈
1.7 django.middleware.clickjacking.XFrameOptionsMiddleware
解释:防止点击劫持,即禁止加载本网页的frame
2.自定义中间件
- process_request()
process_request()
有一个参数,是request。它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,交给下一个中间件处理,如果是HttpResponse对象,Django将不向下执行,直接返回
- process_view()
process_view()有四个参数
- request是HttpRequest对象。
- view_func是Django即将使用的视图函数,其为函数对象使用
view_func.__name__获取其名字
- view_args是将传递给视图的位置参数的列表(即路由参数)
- view_kwargs是将传递给视图的关键字参数的字典(即路由参数)
- Django会在调用视图函数之前调用process_view方法。
它需要返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果
- process_exception()
process_exception()
有两个参数:一个是request,一个exception是视图函数异常产生的Exception对象。
这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行
- process_response()
process_response()
有两个参数,一个是request,一个是response,response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象。
- process_template_response()
process_template_response()
有两个参数,一个HttpRequest对象,response是TemplateResponse对象
实例:
views.py
from django.utils.deprecation import MiddlewareMixin
class GaoMiddleware(MiddlewareMixin):
def process_request(self, request):
print("process_request")
def process_response(self, request, response):
print("process_response")
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(view_func, view_func.__name__)
print(view_args,view_kwargs,'00000000000000')
setting.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',
'testWeb.views.GaoMiddleware' # app的名称.中间件写在的文件名.中间件类名
]