session源码剖析
Posted aaronthon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了session源码剖析相关的知识,希望对你有一定的参考价值。
session机制采用的是一种在客户端与服务端之间保持状态的解决方案,由于采用服务器端保持状态的方案在客户端也要保存标识,session机制也要借助于cookie机制达到目的。session保存了客户的登录信息,但是不需要把用户的所有信息都保存在session中,我们只需要让与用户数据关联的信息保存在session中就可以了。
request.session[“user_id”] = 2 # 设置session 关联id比关联username好,因为username可能不唯一
request.session.get["user_id"] # 取session
接下来看源码:
from django.contrib.sessions.middleware import SessionMiddleware # 点击SessionMiddleware看源码
import time from importlib import import_module from django.conf import settings from django.contrib.sessions.backends.base import UpdateError from django.core.exceptions import SuspiciousOperation from django.utils.cache import patch_vary_headers from django.utils.deprecation import MiddlewareMixin from django.utils.http import cookie_date class SessionMiddleware(MiddlewareMixin): def __init__(self, get_response=None): self.get_response = get_response # 这是个空变量,get_response=None engine = import_module(settings.SESSION_ENGINE) # 用了两个settings self.SessionStore = engine.SessionStore def process_request(self, request):...def process_response(self, request, response):...
先看这个settings,点击
from django.conf import global_settings # 这里面有global_settings,点击看源码 ...... settings = LazySettings()
SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 这个文件里面会看到SESSION_ENGINE
这里面可与看到SESSION_ENGINE是一条配置信息,这里默认将session的信息放到djano数据库里面的session表里面。所以我们可以通过这里面的配置,将session信息放到缓存、文件、Memcache中。另外可以从from django.conf import settings看出,我们这里引用的settings不仅仅是我们django的settings.py文件还有global_settings.py文件,一共两套,先找我们常用的settings.py如果找不到,再去global_settings.py文件里面找。
另外一点值得注意的是:
engine = import_module(settings.SESSION_ENGINE)
# SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ 是一个字符串
# import_module("django.contrib.sessions.backends.db") 和 importdjango.contrib.sessions.backends.db 效果是一样的
# 引入模块之后,再赋值给 engine,所以优先用自己写的engine
就接下来看:
class SessionMiddleware(MiddlewareMixin): def __init__(self, get_response=None): self.get_response = get_response # 这是个空变量,get_response=None engine = import_module(settings.SESSION_ENGINE) # 用了两个settings self.SessionStore = engine.SessionStore # 这里可以看到,因为模块名是engine,所以SessionStore一定是它里面的变量名
继续去看源码:
from django.contrib.sessions.backends import db # 点击db看源码
可以看到,SessionStore是一个类的名字,self.SessionStore这里就是一个类名,所有的功能都封装在SessionStore里面,非常重要。
class SessionStore(SessionBase):...
走到这里,__init__这个函数就执行完了。继续执行process_request方法。
def process_request(self, request): session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) request.session = self.SessionStore(session_key)
先去常用的settings.py文件里找,这里找不到,再去global_settings.py里面找SESSION_COOKIE_NAME,就会看到:
SESSION_COOKIE_NAME = ‘sessionid‘ # 这里拿到了sessionid
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) # 拿到sessin之后进行了一个取的操作,没有sessionid键值对,session_key就是None
所以用户登陆进来,一定会去取这个cookie,无论是第一次还是第二次登陆,不管cookie是不是空的,都要去取cookie里面的sessionid这个键,如果是第一次登陆肯定没有sessionid这个键,如果是第二次第三次登陆肯定有我给你的这个键。
以上是关于session源码剖析的主要内容,如果未能解决你的问题,请参考以下文章
源代码剖析tornado-memcached-sessions —— Tornado session 支持的实现