Skip to content

【源码剖析】tornado-memcached-sessions —— Tornado session 支持的实现(三) #5

Description

@AngryHacker

童鞋,我就知道你是个好学滴好孩子~来吧,让我们进行最后的探(zuo)索(si)!

上一次我们讲到哪里?哦。。。准备讲 SessionManager 是吧,来~一个一个函数看~

首先是初始化,设置密钥, memcache 地址,session 超时时间。

# 初始化需要一个用于 session 加密的 secret, memcache 地址, session 的过期时间def__init__(self, secret, memcached_address, session_timeout):
self.secret=secretself.memcached_address=memcached_addressself.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)
ifraw_data!=None:
# 为了重新刷新 timeoutmc.replace(session_id, raw_data, self.session_timeout, 0)
# 反序列化session_data=pickle.loads(raw_data)
# 如果拿到的数据是字典形式,才进行返回iftype(session_data) ==type({}):
returnsession_dataelse:
return {}
exceptIOError:
return {}

get 经过安全检查后,以 SessionData 的形式返回 memcached 的数据(调用了 _fetch)方法。

defget(self, request_handler=None):
# 获取对应的 session_id 和 hmac_keyif (request_handler==None):
session_id=Nonehmac_key=Noneelse:
# session 的基础还是靠 cookiesession_id=request_handler.get_secure_cookie("session_id")
hmac_key=request_handler.get_secure_cookie("verification")
# session_id 不存在的时候则生成一个新的 session_id 和 hmac_keyifsession_id==None:
session_exists=Falsesession_id=self._generate_id()
hmac_key=self._generate_hmac(session_id)
else:
session_exists=True# 检查 hmac_keycheck_hmac=self._generate_hmac(session_id)
# 不通过则抛出异常ifhmac_key!=check_hmac:
raiseInvalidSessionException()
# 新建 SessionData 对象session=SessionData(session_id, hmac_key)
ifsession_exists:
# 通过 _fetch 方法获取 memcache 中该 session 的所有数据session_data=self._fetch(session_id)
forkey, datainsession_data.iteritems():
session[key] =datareturnsession

至于 set 方法,是为了更新 memcached 的数据。

# 设置新的 session,需要设置 handler 的 cookie 和 memcache 客户端defset(self, request_handler, session):
# 设置浏览器的 cookierequest_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)
# 写入 memcachemc.set(session.session_id, session_data, self.session_timeout, 0)

最后的两个函数,一个是生成 session_id,另一个用 session_id 与密钥加密后生成一个加密字符串,用于验证。

# 生成 session_iddef_generate_id(self):
new_id=hashlib.sha256(self.secret+str(uuid.uuid4()))
returnnew_id.hexdigest()
# 生成 hmac_keydef_generate_hmac(self, session_id):
returnhmac.new(session_id, self.secret, hashlib.sha256).hexdigest()

我们在哪里初始化了 SessionManager 呢?还记得第一篇里面的 Application 类吗?噢...快回去翻翻。

好了,童鞋们我们放学了,大家回家吧~对本篇博客有任何意见,拒绝吐槽!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions