自制session
原理
1、面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ 、__delitem__、__setitem__方法 2、Tornado框架中,默认执行Handler的get/post等方法之前默认会执行 initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作... 3、session其实就是定义在服务器端用于保存用户回话的容器,其必须依赖cookie才能实现。 4、工厂模式,此非必须
示例
# -*- coding:utf-8 -*- # SESSION_ENGINE = "session_code.RedisSession" SESSION_ENGINE = "session_code.CacheSession" SESSION_ID = "__session_id__" EXPIRES = 300 REDIS_HOST = '192.168.11.96' REDIS_PORT = 6379
# -*- coding:utf-8 -*- # 1. "scrapy.middlware.C1" # import importlib # path = "scrapy.middlware.C1" # md,cls = path.rsplit('.',maxsplit=1) # m = importlib.import_module(md) # getattr(m,cls) # 2. 面向对象 # class Foo(object): # # def __getitem__(self, item): # return "123" # # def __setitem__(self, key, value): # pass # # def __delitem__(self, key): # pass # obj = Foo() # v = obj['k1'] # print(v) # obj['k1'] = 666 # del obj['k1'] # request.session['k1'] = 666 # 3. import time import hashlib from . import settings def gen_random_str(): md5 = hashlib.md5() md5.update(str(time.time()).encode('utf-8')) return md5.hexdigest() class CacheSession(object): container = {} def __init__(self,handler): self.handler = handler self.session_id = settings.SESSION_ID self.expires = settings.EXPIRES self.initial() def initial(self): client_random_str = self.handler.get_cookie(self.session_id) if client_random_str and client_random_str in self.container: self.random_str = client_random_str else: self.random_str = gen_random_str() self.container[self.random_str] = {} expires = time.time()+ self.expires self.handler.set_cookie(self.session_id,self.random_str,expires=expires) def __getitem__(self, item): return self.container[self.random_str].get(item) def __setitem__(self, key, value): self.container[self.random_str][key] = value def __delitem__(self, key): if key in self.container[self.random_str]: del self.container[self.random_str][key] class RedisSession(object): def __init__(self,handler): self.handler = handler self.session_id = settings.SESSION_ID self.expires = settings.EXPIRES self.initial() @property def conn(self): import redis conn = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT) return conn def initial(self): client_random_str = self.handler.get_cookie(self.session_id) if client_random_str and self.conn.exists(client_random_str): self.random_str = client_random_str else: self.random_str = gen_random_str() expires = time.time()+ self.expires self.handler.set_cookie(self.session_id,self.random_str,expires=expires) self.conn.expire(self.random_str,self.expires) def __getitem__(self, item): import json data_str = self.conn.hget(self.random_str,item) if data_str: return json.loads(data_str) else: return None def __setitem__(self, key, value): import json self.conn.hset(self.random_str,key,json.dumps(value)) def __delitem__(self, key): self.conn.hdel(self.random_str,key) class SessionFactory(object): @staticmethod def get_session(): from . import settings import importlib engine = settings.SESSION_ENGINE module_path,cls_name = engine.rsplit('.',maxsplit=1) md = importlib.import_module(module_path) cls = getattr(md,cls_name) return cls
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web from tornado.web import RequestHandler from .mysession import SessionFactory class SessionHandler(object): def initialize(self, *args, **kwargs): cls = SessionFactory.get_session() self.session = cls(self) # CacheSession对象,RedisSession对象 class LoginHandler(SessionHandler,RequestHandler): # def initialize(self,*args,**kwargs): # cls = SessionFactory.get_session() # self.session = cls(self) # CacheSession对象,RedisSession对象 # print(self.session.container) def get(self): self.render("login.html") def post(self, *args, **kwargs): user = self.get_argument("user") pwd = self.get_argument("pwd") if user == "alex" and pwd == "123": self.session["user"] = user self.redirect("/index") else: self.render("login.html") class IndexHandler(SessionHandler,RequestHandler): # def initialize(self,*args,**kwargs): # cls = SessionFactory.get_session() # self.session = cls(self) # CacheSession对象,RedisSession对象 # # print(self.session.container) def get(self,*args,**kwargs): user = self.session["user"] print(user) if user: self.write("welcome index") else: self.redirect("/login") sett = { "template_path": "views", } application = tornado.web.Application([ (r"/login", LoginHandler), (r"/index", IndexHandler), ],**sett) # application.reverse_url("n1") if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
1、 def gen_random_str(): # 这个是为了生成随机字符串for session_id md5 = hashlib.md5() md5.update(str(time.time()).encode("utf-8")) return md5.hexdigest() 2、 create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest() 以上均可