基於Tornado自定制仿Django的Session以及Form組件
阿新 • • 發佈:2017-09-14
contain spl exists redirect cookies nco one pytho actor
一、session
1.Session本質是保存在服務器端的數據,可以看作是鍵值對。
用戶第一次打開網站頁面
- 生成一段隨機字符串,作為value發給客戶端瀏覽器,客戶端帶著字符串獲取對應的session
- 在session中保存,隨機字符串作為key,value={‘user‘:‘Mitsui‘,‘pwd‘:123....}
2.session模塊代碼:
import time import hashlib import settings def get_random_str(): """ 獲取作為session key的隨機字符串 :return: """ md5 = hashlib.md5() md5.update(str(time.time()).encode(‘utf-8‘)) return md5.hexdigest() class RedisSession(object): def __init__(self,handler): """ 基於Redis在服務端存儲session :param handler: """ self.handler = handler self.session_id = settings.SESSION_ID self.expires = settings.EXPIRERS self.initial() @property def conn(self): import redis conn = redis.Redis(host=‘192.168.xx.xx‘,port=6379) 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 = get_random_str() expires = time.time() + self.expires self.handler.set_cookie(self.session_id,self.random_str,expires=expires) #除了對瀏覽器cookies設置超時時間,也需要對redis數據設置超時時間,可以定時清除數據節省空間 self.conn.expire(self.random_str,self.expires) def __getitem__(self, item): """ 取session,item為key,如self.session[‘user‘] :param item: :return: """ import json #由於Python數據類型直接存入redis後受到轉換,因此在存儲時會先dumps,相應的取值時會先loads。 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): """ 設置session :param key: :param value: :return: """ import json self.conn.hset(self.random_str,key,json.dumps(value)) def __delitem__(self, key): """ 刪除session :param key: :return: """ self.conn.hdel(self.random_str) class CacheSession(object): container = {} def __init__(self,handler): """ 普通的內存存取session :param handler: 視圖函數傳進的self,可以使用get_cookie等方法 """ self.handler = handler self.session_id = settings.SESSION_ID #存儲在瀏覽器的cookies的key self.expires = settings.EXPIRERS #超時時間 self.initial() def initial(self): """ :return: """ client_random_str = self.handler.get_cookie(self.session_id) if client_random_str and client_random_str in self.container: #如果session中已經有值,賦原值刷新超時時間 self.random_str = client_random_str else: #沒有則獲取隨機字符串 作為session的key存儲在內存中container,並設置超時時間, self.random_str = get_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): """ 獲取session :param item:key, session[‘user‘] :return: """ return self.container[self.random_str].get(item) def __setitem__(self, key, value): """ 設置session :param key: session[‘user‘] :param value: =user :return: """ self.container[self.random_str][key] = value def __delitem__(self, key): """ 刪除session del self.session時觸發 :param key: :return: """ if key in self.container[self.random_str]: del self.container[self.random_str][key] class SessionFactory(object): """ 讀取配置文件,根據配置文件返回定制的session類 """ @staticmethod def get_session(): 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
3.基於Tornado的使用:
import tornado.ioloop import tornado.web from tornado.web import RequestHandler from session_code import SessionFactory class SessionHandler(object): def initialize(self,*args,**kwargs): cls = SessionFactory.get_session() # cls是CacheSession對象,RedisSession對象 #執行cls的init方法 self.session = cls(self) class LoginHandler(SessionHandler,RequestHandler): """ init方法執行之後,執行get 跟post方法之前,會先執行initialize方法, 這裏用多繼承的方法繼承自SessionHandler,執行initialize方法,獲取 CacheSession或者RedisSession對象的session方法 """ def get(self, *args, **kwargs): self.render("login.html") def post(self, *args, **kwargs): user = self.get_argument(‘user‘) pwd = self.get_argument(‘pwd‘) if user == "Mitsui" and pwd == ‘123‘: self.session[‘user‘] = user self.redirect(‘/index‘) else: self.render(‘login.html‘) class IndexHandler(SessionHandler,RequestHandler): def get(self, *args, **kwargs): user = self.session[‘user‘] if user: self.write(‘歡迎登錄!‘) else: self.redirect(‘/login‘) sett = { ‘template_path‘:‘views‘, #XSRF ‘xsrf_cookies‘:True, } application = tornado.web.Application([ (r"/login",LoginHandler), (r"/index",IndexHandler), ],**sett) if __name__ == ‘__main__‘: application.listen(8888) tornado.ioloop.IOLoop.instance().start()
配置文件settings:
#所選的session處理類 SESSION_ENGINE = "session_code.CacheSession" #客戶端cookie中保存的key SESSION_ID = "__session__id__" #超時時間 EXPIRERS = 300
基於Tornado自定制仿Django的Session以及Form組件