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源码剖析的主要内容,如果未能解决你的问题,请参考以下文章

golang:mgo剖析之Session

源代码剖析tornado-memcached-sessions —— Tornado session 支持的实现

tomcat(12)org.apache.catalina.core.StandardContext源码剖析

《Docker 源码分析》全球首发啦!

Mybatis源码剖析:传统开发方式源码剖析

Spark源码剖析:stage划分原理与源码剖析