1. 程式人生 > >深入理解flask框架(4):session

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

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): return httponly = 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 = Nonedef 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類與第一章類似,而模板與訊號部分因為當前的前後端分離的趨勢,以後用的應該越來越少。
這個系列就此完結。
以上。