首页技术文档Python › 给 tornado加上session支持

给 tornado加上session支持

阅读本文需要具有使用python编程的能力以及Web编程的经验,起码应该知道python是什么,Session是什么。初学者慎入,某些描述 语焉不详,小心误入歧途,欢迎高手踊跃拍砖。本文代码仅仅作为示例使用,用于说明在tornado中实现session的过程以及方法,未经过任何编译或 者运行,请勿直接copy到项目中使用,本人不对此行为造成的后果负任何责任。(此文实现内容源于商业项目,恕未能直接提供源码)

———————————————————-

tornado没有提供默认的会话,而很多敏感信息又没法用cookie存,tornado提供的secure_cookie只是解决了防止 cookie篡改而没法阻止数据被解密为明文,所以我就给tornado写了一个session的包来解决这个问题。嗯,我们来看看是如何从底层一砖一瓦 的来实现Session的功能。

根据项目的需要我采用Memcached作为Session的backend,当然你愿意用Mysql 或者是其他什么能存储数据的东西都行,比如文本文件或者mongodb,选择很多,所以我们将Session需要持久化的操作独立出来成为一个可以替换的 backend模块,我们可以根据配置使用不同的backend,由于python得ducktyping特性,要实现起来相当的简单,我们只需要提供包 含如下三个方法签名的类就行了

class backend():

def getitem(self,key):

def setitem(self,key,value,timeout)

def deleteitem(self,key)

对于Memcached我们需要在backend类中保持一 个Memcached的连接,大体上的实现如下:

from memcache import Client

class backend():

def __init__(self):

self.conn=Client([‘127.0.0.1:11211’])

def getitem(self,key):

return self.conn.get(key)

def setitem(self,key,value,timeout):

self.conn.set(key,value,timeout)

def deleteitem(self,key):

self.conn.delete(key)

当然实际应用中我们不会写得这么简陋了,连接的服务器信息都是 从配置文件里取得的。这样我们就有了一个Session的backend了,如果你想用Mysql作为backend,那么可以按照这个原理来改写一个 backend类

有了Session数据的持久化backend后我们就可以开始编写Session类本身了,首先我们来回顾一下 Session的工作原理。基本上大部分的Session都是通过Cookie配置服务端持久化来实现Session的,cookie保持用户创建会话的 SessionID,然后在每次访问的时候通过SessionID到持久化服务中去取这个Session的数据。当一个request开始的时候过程如下 图:

image

当 一个request结束之后,过程如下图:

image

理清楚处理的逻辑我们就 能开始编码了,首先我们需要用一个对象来存储Session的数据,一般来说Session都按照Key-Value的形式存储,所以我们可以用一个 Dict来作为Session的存储对象,但是我们还需要一个Session ID,所以我们继承一个dict

class SessionData(dict):

def __inti__(self,id=none):

self.id=id

def __getitem__(self,key):

if self.has_key(key):

return self[key]

return None

def __setitem__(self,key,value):

self[key]=value

然后我们实现一个decorator来在一个request前和request后来恢复和保存 Session

def Session(request):

def Process(handler,*args):

#请求前恢复Session对象的过程

item=handler.application.backend.getitem(handler.get_secure_cookie(‘session_id’,’’))

data=None

if item:

data=new SessionData(item.id)

data.update(item)

else:

data=new SessionData()

handler.set_secure_cookie(“session_id”,””)

handler.setattr(“session”,data)

request(handler,*args)#执行原本请求的方法

#请求完成后保存session的过程

if data.id:

handler.application.backend.setitem(data.id,data)

else:

if len(data.keys()):

data.id=str(uuid1.uuid1())

handler.set_secure_cookie(“session_id”,data.id)

handler.application.backend.setitem(data.id,data)

这个方 法有点长,不过逻辑就是这么样子的,实现了这个decreator之后我们只需要在需要使用Session的请求前加上@Session,就能够通过 self.session来使用session咯。

接下来想在项目里使用还有一些具体的问题要解决,但是基本原理 和实现方式在本文的内容就到此为止了,接下来的工作应该难不倒能看懂此文的同学,如果看着如同天书,那么多半是对python或者tornado没有什么 了解,请自行弥补基础知识。希望此文能够对正在实践python和tornado的TX有所帮组

本站技术交流群:24735919,欢迎大家进群交流探讨!

1 Comments.[ Leave a comment ]

  1. 亚历山大同志

发表评论