新地址:https://github.com/AngryHacker/articles/issues/5#issue-372211594
童鞋,我就知道你是個好學滴好孩子~來吧,讓我們進行最後的探(zuo)索(si)!
上一次我們講到哪裏?哦。。。準備講 SessionManager 是吧,來~一個一個函數看~
首先是初始化,設置密鑰, memcache 地址,session 超時時間。
# 初始化需要一個用於 session 加密的 secret, memcache 地址, session 的過期時間
def __init__(self, secret, memcached_address, session_timeout):
self.secret = secret
self.memcached_address = memcached_address
self.session_timeout = session_timeout
接着是 _fetch 方法,以 session_id 爲鍵從 memcached 中取出數據,並用 pickle 反序列化解析數據:
# 該方法用 session_id 從 memcache 中取出數據
def _fetch(self, session_id):
try:
# 連接 memcache 服務器
mc = memcache.Client(self.memcached_address, debug=0)
# 獲取數據
session_data = raw_data = mc.get(session_id)
if raw_data != None:
# 爲了重新刷新 timeout
mc.replace(session_id, raw_data, self.session_timeout, 0)
# 反序列化
session_data = pickle.loads(raw_data)
# 如果拿到的數據是字典形式,才進行返回
if type(session_data) == type({}):
return session_data
else:
return {}
except IOError:
return {}
get 經過安全檢查後,以 SessionData 的形式返回 memcached 的數據(調用了 _fetch)方法。
def get(self, request_handler = None):
# 獲取對應的 session_id 和 hmac_key
if (request_handler == None):
session_id = None
hmac_key = None
else:
# session 的基礎還是靠 cookie
session_id = request_handler.get_secure_cookie("session_id")
hmac_key = request_handler.get_secure_cookie("verification")
# session_id 不存在的時候則生成一個新的 session_id 和 hmac_key
if session_id == None:
session_exists = False
session_id = self._generate_id()
hmac_key = self._generate_hmac(session_id)
else:
session_exists = True
# 檢查 hmac_key
check_hmac = self._generate_hmac(session_id)
# 不通過則拋出異常
if hmac_key != check_hmac:
raise InvalidSessionException()
# 新建 SessionData 對象
session = SessionData(session_id, hmac_key)
if session_exists:
# 通過 _fetch 方法獲取 memcache 中該 session 的所有數據
session_data = self._fetch(session_id)
for key, data in session_data.iteritems():
session[key] = data
return session
至於 set 方法,是爲了更新 memcached 的數據。
# 設置新的 session,需要設置 handler 的 cookie 和 memcache 客戶端
def set(self, request_handler, session):
# 設置瀏覽器的 cookie
request_handler.set_secure_cookie("session_id", session.session_id)
request_handler.set_secure_cookie("verification", session.hmac_key)
# 用 pickle 進行序列化
session_data = pickle.dumps(dict(session.items()), pickle.HIGHEST_PROTOCOL)
# 連接 memcache 服務器
mc = memcache.Client(self.memcached_address, debug=0)
# 寫入 memcache
mc.set(session.session_id, session_data, self.session_timeout, 0)
最後的兩個函數,一個是生成 session_id,另一個用 session_id 與密鑰加密後生成一個加密字符串,用於驗證。
# 生成 session_id
def _generate_id(self):
new_id = hashlib.sha256(self.secret + str(uuid.uuid4()))
return new_id.hexdigest()
# 生成 hmac_key
def _generate_hmac(self, session_id):
return hmac.new(session_id, self.secret, hashlib.sha256).hexdigest()
我們在哪裏初始化了 SessionManager 呢?還記得第一篇裏面的 Application 類嗎?噢...快回去翻翻。
好了,童鞋們我們放學了,大家回家吧~對本篇博客有任何意見,拒絕吐槽!