全局对象session解析
接下来我们来看看flask的session对象,session对象也来自与globals.py文件,现贴出session对象的产生逻辑的源码:
from functools import partial
from werkzeug.local import LocalProxy
from werkzeug.local import LocalStack
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError(_request_ctx_err_msg)
return getattr(top, name)
_request_ctx_stack = LocalStack()
session = LocalProxy(partial(_lookup_req_object, "session"))由LocalProxy(partial(_lookup_req_object, "session"))可知,session来自request上下文的session属性,接下来看一下session的具体处理逻辑和生命周期:
class Flask(_PackageBoundObject):
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except: # noqa: B001
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)我们回忆下reqeust上下文的实例化逻辑,来找寻session的踪迹:
由代码可知RequestContext实例化时,对session进行初始化,默认为None,而后在push方法中,针对不同的session值,进行不同的处理。接下来具体的分析一下:
如果session为None时,将其值赋为session_interface.open_session的返回值,session_interface为self.app.session_interface, 即Flask类的session_interface,默认为flask.sessions.SecureCookieSessionInterface的实例化对象,那flask.sessions.SecureCookieSessionInterface的实现原理如何,我们从源码中发现秘密:
SecureCookieSessionInterface.open_session方法中,首先获取序列化实例s,由get_signing_serializer可知,当Flask的SECRET_KEY为None, s值也为None,open_session直接返回None,否则继续获取request的cookies,cookies的key为app.session_cookie_name, 默认值为session,翻看Flask的源码,发现这里使用的是python的数据描述符类,关于此概念可以自行百度,才能具体理解此处的妙用。最后返回self.session_class实例化对象,self.session_class默认为session.py中的SecureCookieSession类。
继续看当self.session为None时,将会重新赋值为session_interface.make_null_session(self.app),我们看一下make_null_session的具体实现: 需要注意的是SecureCookieSessionInterface中并未发现make_null_session方法,但是在父类SessionInterface中实现了此方法,下面看一下具体的代码:
看代码的实现方式,当Flask的配置SECRET_KEY为None,session将会是不可用。默认为NullSession的实例,此对象将不能进行任何操作。当我们启用session时,即SECRET_KEY不为None,此时我们的session将在response返回给客户端是进行save_session操作,即下面的逻辑:
可以看到我们对cookie的修改将会在cookie未过期之前一直保留,并通过itsdangerous库进行序列化和反序列化。至此session的基本逻辑已介绍完毕,具体的代码还需要我仔细去读才能理解。
Last updated
Was this helpful?