深入理解flask框架(4):session

2018-01-13 10:59:41来源:segmentfault作者:凌霄人点击

分享

flask中session的实现是基于cookie。
打开flask源码的session.py文件,我们可以看到最后的接口类中,主要有open_session,save_session两个函数。


class SecureCookieSessionInterface(SessionInterface):
.....
def open_session(self, app, request):
s = self.get_signing_serializer(app)
if s is None:
return None
val = request.cookies.get(app.session_cookie_name)
if not val:
return self.session_class()
max_age = total_seconds(app.permanent_session_lifetime)
try:
data = s.loads(val, max_age=max_age)
return self.session_class(data)
except BadSignature:
return self.session_class()def save_session(self, app, session, response):
domain = self.get_cookie_domain(app)
path = self.get_cookie_path(app)# If the session is modified to be empty, remove the cookie.
# If the session is empty, return without setting the cookie.
if not session:
if session.modified:
response.delete_cookie(
app.session_cookie_name,
domain=domain,
path=path
)return# Add a "Vary: Cookie" header if the session was accessed at all.
if session.accessed:
response.vary.add('Cookie')if not self.should_set_cookie(app, session):
returnhttponly = self.get_cookie_httponly(app)
secure = self.get_cookie_secure(app)
expires = self.get_expiration_time(app, session)
val = self.get_signing_serializer(app).dumps(dict(session))
response.set_cookie(
app.session_cookie_name,
val,
expires=expires,
httponly=httponly,
domain=domain,
path=path,
secure=secure
)

Flask类中对session的接口进行了初始化,并在process_response函数中进行了调用,但是只有save_session接口,那么open_session接口在哪里被调用呢?


session_interface = SecureCookieSessionInterface()def process_response(self, response):
.....
if not self.session_interface.is_null_session(ctx.session):
self.session_interface.save_session(self, ctx.session, response)
.....

答案就是在request上下文进栈的时候会进行调用


class RequestContext(object):

self.session = None

def push(self):
....
if self.session is None:
session_interface = self.app.session_interface
self.session = session_interface.open_session(
self.app, self.request
)if self.session is None:
self.session = session_interface.make_null_session(self.app)

这样我们可以梳理一下flask中session产生的整个过程。
当调用的wsgi函数执行到push时,


ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()

push函数判断self.session是否为None,如果为None,则调用open_session进行初始化,这个过程等价于


self.session = self.session_class()

而session_class在SecureCookieSessionInterface中定义为


session_class = SecureCookieSession

而SecureCookieSession则是一个自定义的类实现了类似字典的接口,则此时可以理解为self.session = {},
之后在finalize_request函数中调用


response = self.process_response(response)
接下来
|
|
|
self.session_interface.save_session(self, ctx.session, response)
接下来
|
|
|
调用set_cookie对cookie进行设置
response.set_cookie(
app.session_cookie_name,
val,
expires=expires,
httponly=httponly,
domain=domain,
path=path,
secure=secure
)

之后不会在写了,blueprint类与第一章类似,而模板与信号部分因为当前的前后端分离的趋势,以后用的应该越来越少。
这个系列就此完结。
以上。

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台