【Django】源码分析之session生命周期
来源:互联网 发布:淘宝2016春秋连衣裙 编辑:程序博客网 时间:2024/06/12 00:22
Web应用中session是至关重要的一个概念,有了它http就有了状态。 我们才能方面的开发出各种基于用户的应用。说到session 不得不说cookies,不过cookies在服务端基本没有太多需要实现的逻辑,基本就是存取和报文格式之类,所以不做研究。 (下面是根据django1.8代码分析)
session在django源码中的主要配置(django/contrib/sessions),主要的几个点
* session的存取,浏览器交互
* session key 的生成 以及 内容的序列化(默认使用json序列化)
* session存储 默认存储在数据库中(cookies 还是文件 或者是db等)
总得来说还是比较简单,自己很容易也可以造个轮子。
本文地址 http://blog.csdn.net/orangleliu/article/details/75045962
概览
先看下django全局默认配置中session相关的地方, 我们可以根据需要自行修改
############# SESSIONS #############SESSION_CACHE_ALIAS = 'default' # Cache to store session data if using the cache session backend.SESSION_COOKIE_NAME = 'sessionid' # Cookie name. This can be whatever you want.SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # Age of cookie, in seconds (default: 2 weeks).SESSION_COOKIE_DOMAIN = None # A string like ".example.com", or None for standard domain cookie.SESSION_COOKIE_SECURE = False # Whether the session cookie should be secure (https:// only).SESSION_COOKIE_PATH = '/' # The path of the session cookie.SESSION_COOKIE_HTTPONLY = True # Whether to use the non-RFC standard httpOnly flag (IE, FF3+, others)SESSION_SAVE_EVERY_REQUEST = False # Whether to save the session data on every request.SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether a user's session cookie expires when the Web browser is closed.SESSION_ENGINE = 'django.contrib.sessions.backends.db' # The module to store session dataSESSION_FILE_PATH = None # Directory to store session files if using the file session module. If None, the backend will use a sensible default.SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer' # class to serialize session data
- 在浏览器端也是通过cookie来存储session的name和key(完全基于cookie),所以有一些cookies属性需要设置
- django中session模块是以中间件的形式提供的(在MIDDLEWARE_CLASSES中设置) 会在response阶段对session进行处理 设置session cookie
- session 对象有这几个属性
key ,data ,过期时间
, 通过session表很容易看到 - 存储的过程: session内容存在一个字典中,对字典进行序列化,然后hmc加salt的一次hash,”hashvalue:序列化数据” 在用base64编码一次,把session data变成string在存储
说说源码
简单描述下最核心的2个问题,session生成的过程? session 取出更新的过程?
session表的定义 django/contrib/sessions/base_session.py
class AbstractBaseSession(models.Model): session_key = models.CharField(_('session key'), max_length=40, primary_key=True) session_data = models.TextField(_('session data')) expire_date = models.DateTimeField(_('expire date'), db_index=True)
简单的流程
session_dict--> encode(session_dict) --> 存储
默认的 SESSION_ENGINE 是 ‘django.contrib.sessions.backends.db’, 看看这里基本就知道session操作了,还是上面的流程
看看session的获取
根据 cookies 中 sessionid 获取 session key ---> 获取数据 ----> decode 数据得到 session_dict
decode , encode 主要在 django/contrib/sessions/backends/base.py
中,也很简单。
def encode(self, session_dict): "Return the given session dictionary serialized and encoded as a string." serialized = self.serializer().dumps(session_dict) hash = self._hash(serialized) return base64.b64encode(hash.encode() + b":" + serialized).decode('ascii') def decode(self, session_data): encoded_data = base64.b64decode(force_bytes(session_data)) try: # could produce ValueError if there is no ':' hash, serialized = encoded_data.split(b':', 1) expected_hash = self._hash(serialized) if not constant_time_compare(hash.decode(), expected_hash): raise SuspiciousSession("Session data corrupted") else: return self.serializer().loads(serialized) except Exception as e: # ValueError, SuspiciousOperation, unpickling exceptions. If any of # these happen, just return an empty dictionary (an empty session). if isinstance(e, SuspiciousOperation): logger = logging.getLogger('django.security.%s' % e.__class__.__name__) logger.warning(str(e)) return {}
session 使用的时候会涉及到一些 settings中配置,主要看 django.contrib.session.middleware.SessionMiddleware 就行了,session使用的好例子。
调试
下面是采用db存储下,一些调试结果, 参照上面 encode, decode 部分代码
请求进来之后 到 SessionMiddleware , process_request 方法读取配置中 session 的 cookie name 为 'sessionid', 从cookies取出 sessionid 的cookie,它的值就是 django中一个 session key然后从存储取出 session 对象,放在 request 对象中。例如 session_key 为 'ywptdguqbjt7ws6ysp4ztyx18vsazrx0'查找session的 序列化配置 默认为 'django.contrib.sessions.serializers.JSONSerializer'根据session key,当前时间 从数据库查找没过期的记录然后decode session_data,b64decode 得到 '10754efe4d110a7aba657311c37513cee5841cd9:{}' 格式为 hashvalue:serializeddata 两部分hashvalue 是对 serializeddata 之后的字符串做校验之用,防止有人直接篡改数据库,如果 hashvalue == hash(serializeddata ), 然后 反序列化serializeddata 得到一个 dict对象。存,更新 session ,数据加工顺序相反。
经验
最好有分布式内存缓存的集群来存储。 auth验证的时候会大量的读取session。
session清除
Django 优化小技巧之清除过期session 使用数据库存储session不会主动删除,过期数据太多势必影响性能。
db + cache来存储session
这样做可以提高性能,虽然存储时候慢了一点点,读取会快很多,适合session读取较多场合。
如果session是存储在关系型数据库中,是可以在数据库上在配置一个cache层的,django提供了这么一种机制。如果开启了cache,如果应用中有session相关操作,要注意从cached_db 和从db中直接取出session产生的内容过期问题。因为session的值 即会在数据库中持久化,也会在cache引擎中存储(在过期之前)。 最好操作 cached_db 会自动同步相同的操作到db中
- 【Django】源码分析之session生命周期
- Django源码分析之server
- Django session源码阅读
- Django源码分析之执行入口
- Django源码分析之权限系统
- zuul源码分析之Request生命周期管理
- libjingle源码分析之:Session和Transport
- 云客Drupal8源码分析之Session系统
- Zookeeper源码分析之二Session建立
- 云客Drupal8源码分析之Session进阶
- CI框架源码分析之Session类Session.php
- JSP之Session生命周期
- Django源码分析--引导
- django源码分析
- Django源码分析--1
- PHP源码分析之session.auto_start配置分析
- Django Form源码分析之BaseForm验证逻辑
- Django Form源码分析之Field验证逻辑
- 2017-7-12 文本处理工具
- C++中NULL和nullptr的区别
- 3.Dagger2创建和区分不同的实例
- iOS -- GCD之延迟与定时器
- 安卓中的坐标系
- 【Django】源码分析之session生命周期
- 移动端网页中viewport、retina、高清图、dp单位等详解
- 桥初始化(一)
- CSDN安全设置需改进
- CSS基础知识
- 【问题汇总】python操作hbase脚本
- 启动 eclipse 报错:Failed to load the JNI shared jvm.dll
- Professional JS(六-Understanding the object&&factory/constructor/prototype pattern)&enumerable
- Struts2入门(一)