Django中间件分析
SessionMiddleware
浏览器会发送包含SESSION_COOKIE_NAME的的Cookie 中间件从django_session中按照SESSION_COOKIE_NAME取出存入的session,
设置request中的session属性(SessionStore),包括_auth_user_id,_auth_user_backend,_auth_user_hash等
返回response时同步session和返回给浏览器的cookie状态 源码:
class SessionMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
#初始化session,django启动时执行一次
self.get_response = get_response
engine = import_module(settings.SESSION_ENGINE)
self.SessionStore = engine.SessionStore def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) #从cookie中读取sessionkey
request.session = self.SessionStore(session_key) #根据sessionkey从django_session中读取session def process_response(self, request, response):
"""
If request.session was modified, or if the configuration is to save the
session every time, save the changes and set a session cookie or delete
the session cookie if the session has been emptied.
"""
try:
accessed = request.session.accessed
modified = request.session.modified
empty = request.session.is_empty()
except AttributeError:
pass
else:
# First check if we need to delete this cookie.
# The session should be deleted only if the session is entirely empty
# 如果cookie有sessionid并且请求中session是空的,将cookie中的session置空
if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
response.delete_cookie(
settings.SESSION_COOKIE_NAME,
path=settings.SESSION_COOKIE_PATH,
domain=settings.SESSION_COOKIE_DOMAIN,
)
else:
if accessed:
patch_vary_headers(response, ('Cookie',))
# 如果更改过session并且请求中的session非空,保存session数据,并且更新返回的cookie(返回状态500除外)
if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
if request.session.get_expire_at_browser_close():
max_age = None
expires = None
else:
max_age = request.session.get_expiry_age()
expires_time = time.time() + max_age
expires = http_date(expires_time)
# Save the session data and refresh the client cookie.
# Skip session save for 500 responses, refs #3881.
if response.status_code != 500:
try:
request.session.save()
except UpdateError:
raise SuspiciousOperation(
"The request's session was deleted before the "
"request completed. The user may have logged "
"out in a concurrent request, for example."
)
response.set_cookie(
settings.SESSION_COOKIE_NAME,
request.session.session_key, max_age=max_age,
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
path=settings.SESSION_COOKIE_PATH,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None,
samesite=settings.SESSION_COOKIE_SAMESITE,
)
return response
AuthenticationMiddleware
比较简单,根据request请求设置request中的user和cache user,返回的为惰性加载对象
源码:
如果此时传入的request中有_cached_user,则会跳过从request中获取登录对象的操作
def get_user(request):
if not hasattr(request, '_cached_user'):
request._cached_user = auth.get_user(request)
return request._cached_user
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
#必选先执行session middleware,不然报错
assert hasattr(request, 'session'), (
"The Django authentication middleware requires session middleware "
"to be installed. Edit your MIDDLEWARE%s setting to insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
#request.user为从request中得到的用户
request.user = SimpleLazyObject(lambda: get_user(request))
Django中间件分析的更多相关文章
- Django中间件之SessionMiddleware源码分析
settings.py文件中 MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', ] # from djang ...
- Django数据操作F和Q、model多对多操作、Django中间件、信号、读数据库里的数据实现分页
models.tb.objects.all().using('default'),根据using来指定在哪个库里查询,default是settings中配置的数据库的连接名称. 外话:django中引 ...
- Django学习之七:Django 中间件
目录 Django 中间件 自定义中间件 - - - 大体两种方式 将中间件移除 实例 中间件加载源码阅读 总结 Django 中间件 Tips: 更新日志: 2019.01.31 更新django中 ...
- Django中间件加载原理
假设我们有如下中间件: setting.py文件 MIDDLEWARE = [ 'django.middleware.A', 'django.middleware.B', 'django.middle ...
- Django中间件-跨站请求伪造-django请求生命周期-Auth模块-seettings实现可插拔配置(设计思想)
Django中间件 一.什么是中间件 django中间件就是类似于django的保安;请求来的时候需要先经过中间件,才能到达django后端(url,views,models,templates), ...
- django 中间件
django处理一个Request的过程是首先通过django 中间件,然后再通过默认的URL方式进行的.所以说我们要做的就是在django 中间件这个地方把所有Request拦截住,用我们自己的方式 ...
- day20 FORM补充(随时更新),F/Q操作,model之多对多,django中间件,缓存,信号
python-day20 1.FROM生成select标签的数据应该来源于数据库. 2.model 操作 F/Q (组合查询) 3.model 多对多操作. 4.中间件 :在请求到达url前先会经过 ...
- Django中间件的使用
Django中间件的使用 中间件(middleware) 中间件应用于request与服务端之间和服务端与response之间,客户端发起请求到服务端接收可以通过中间件,服务端返回响应与客户端接收响应 ...
- Django中间件 及 form 实现用户登陆
Django中间件 及 form 实现用户登陆 Form 验证 密码调用md5 加密存储 form.add_error("字段名", "错误信息") 自定义错误 ...
随机推荐
- SQLite加密 wxSqlite3
一直在网上搜wxSqlite3的文档,但是总找不到能真正解决问题的,就是一个简单的编译wxSqlite3自带的示例也出了老多问题,后来却发现,其实wxSqlite3的readme中已经有了详细的方法, ...
- Spark 读写数据、抽象转换 拾遗
读 package com.test.spark import org.apache.spark.sql.{Dataset, Row, SaveMode, SparkSession} /** * @a ...
- Linux负载均衡利器(LVS)
LVS是什么? LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统.本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之 ...
- 自己写一个依赖注入容器Container
前言:在平时的写代码中为了解耦.方便扩展,经常使用一些DI容器(如:Autofac.Unity),那是特别的好用. 关于它的底层实现代码 大概是这样. 一.使用依赖注入的好处 关于使用依赖注入创建对象 ...
- <scrapy爬虫>爬取360妹子图存入mysql(mongoDB还没学会,学会后加上去)
1.创建scrapy项目 dos窗口输入: scrapy startproject images360 cd images360 2.编写item.py文件(相当于编写模板,需要爬取的数据在这里定义) ...
- USACO training course Number Triangles 数塔 /// DP oj10122
题目大意: ...就是数塔 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 7+3+8+7+5=30 ...
- Input:type属性
1.button:定义可点击的按钮(通常与 JavaScript 一起使用来启动脚本). <input id="" type="button" name= ...
- java关于lombok(包括父类参数)
java关于lombok对bean对象进行自动设置 使用说明 使用方式 注释类型 @NonNull @Data(常用) @NoArgsConstructor(常用)/@RequiredArgsCons ...
- python基础语法(数据类型转换)
- ON_WM_TIMER() void (__cdecl xx::* )(UINT)”转换为“void (__cdecl CWnd::* )(UINT_PTR)
ON_WM_TIMER()在编译器从32位转换为64位的时候, 出现的问题; class CFlatComboBox : public CComboBox (基类为CWnd) 为了重载CWnd的 ...