Tronado自定義Session
阿新 • • 發佈:2019-03-25
from 1-1 create 必須 int 偽造 lis dom 字典
這裏就不一一訴說Session和Cookie直接的關系了,下面以一張圖來概括:
下面是一個簡單的Tornaod自定義Session的例子,看完後你可能會明白為什麽我們在Django裏可以直接使用request.session來獲取或者設置鍵值對的原因,在這個例子中包含了許多調用類裏面的方法,例如__contains__ , __getitem__ , __setitem__ , __delitem__等:
版本1:
import tornado.ioloop import tornado.web import time,hashlib from controllers.account import LoginHandlerVersion 1from controllers.home import HomeHandler container = {} # container = { ‘隨機字符串或者cookie‘:{‘uuuu‘:‘root‘,‘k1‘:‘v1‘}, } class Session(object): def __init__(self,handler): self.handler = handler self.random_str = None # 隨機字符串,也有可能是cookie self.client_random_str= self.handler.get_cookie(‘session_id‘) print(‘哪裏來的str‘,self.client_random_str) if not self.client_random_str: """新用戶,沒有cookie的""" # 1. 生成隨機字符串當作session中的key,保存在大字典container中,用戶每次訪問都到裏面找是否有該值 self.random_str = self.create_random_str() container[self.random_str]= {} # 保存在大字典 else: if self.client_random_str in container: """老用戶,在container大字典裏面了""" self.random_str = self.client_random_str print(‘老用戶‘,container) else: """非法用戶,偽造的cookie""" self.random_str = self.create_random_str() container[self.random_str] = {} # 2. 生成cookie,必須調用LoginHandler才能使用set_cookie() timeOut = time.time() self.handler.set_cookie(‘session_id‘,self.random_str,expires=timeOut+1800) # 3. 寫入緩存或數據庫 ==> 後面用戶自己調用session[‘uuuu‘] = ‘root‘ def create_random_str(self): now = str(time.time()) m = hashlib.md5() m.update(bytes(now,encoding=‘utf-8‘)) return m.hexdigest() def __setitem__(self, key, value): # print(key,value) # key 就是用戶自己設置session[‘uuuu‘]=‘root‘中的uuuu,value就是root container[self.random_str][key] = value # print(‘setitem‘,container) def __getitem__(self, item): # print(item) # uuuu # print(‘getitem‘,container) return container[self.random_str].get(item) def __delitem__(self, key): pass def open(self): pass def cloes(self): pass class Foo(object): def initialize(self): # print(self) # <__main__.LoginHandler object at 0x00000000038702E8> self.session = Session(self) super(Foo, self).initialize() # 執行RequestHandler中的initialize class HomeHandler(Foo,tornado.web.RequestHandler): def get(self): print(‘session‘,self.session) user = self.session[‘uuuu‘] # 調用Session類中的__getitem__方法, 獲取value print(‘user‘,user) if not user: self.write(‘不是合法登錄‘) else: self.write(user) class LoginHandler(Foo,tornado.web.RequestHandler): def get(self): # self.session[‘uuuu‘] # 調用Session類中的__getitem__方法, 獲取value # del self.session[‘uuuu‘] # 調用Session類中的__delitem__方法, 刪除 self.session[‘uuuu‘] = "root" # 調用Session類中的__setitem__方法,在session裏面設置了uuuu self.write("Hello, world") print(container) self.redirect(‘/home‘) application = tornado.web.Application([ # (r"/index", MainHandler), (r"/login", LoginHandler), (r"/home", HomeHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
版本2,可根據需要將session寫入緩存或者數據庫,下面以寫入Cache為例:
import tornado.ioloop import tornado.web import time,hashlib from controllers.account import LoginHandler from controllers.home import HomeHandler container = {} # container = { ‘隨機字符串或者cookie‘:{‘uuuu‘:‘root‘,‘k1‘:‘v1‘}, } class Cache(object): """將session保存在內存""" def __init__(self): # self.container = {} pass def __contains__(self, item): print(‘__contains__:‘,item) return True def initial(self,random_str): container[random_str] = {} def get(self,random_str,key): return container[random_str].get(key) def set(self,random_str,key,value): container[random_str]={} container[random_str][key] = value def delete(self,random_str,key): del container[random_str][key] def open(self): pass def close(self): pass def clear(self,random_str): del container[random_str] class Memcache(object): def __init__(self): pass def get(self,key): pass def set(self,key,value): pass def delete(self,key): pass def open(self): pass def close(self): pass P = Cache # 3. 可以是Memcache,根據用戶自己選擇要寫入緩存還是數據庫... class Session(object): def __init__(self,handler): self.handler = handler self.random_str = None # 隨機字符串,也有可能是cookie self.ppp = P() # 去用戶請求信息中獲取session_id,如果沒有,新用戶 self.client_random_str = self.handler.get_cookie(‘session_id‘) if not self.client_random_str: "新用戶" self.random_str = self.create_random_str() container[self.random_str] = {} else: if self.client_random_str in self.ppp: "老用戶" self.random_str = self.client_random_str else: "非法用戶" self.random_str = self.create_random_str() self.ppp.initial(self.random_str) # 2. 生成cookie,必須調用LoginHandler才能使用set_cookie() timeOut = time.time() self.handler.set_cookie(‘session_id‘,self.random_str,expires=timeOut+1800) # 3. 寫入緩存或數據庫 Cahce、Memcache ==> 後面用戶自己調用session[‘uuuu‘] = ‘root‘ def create_random_str(self): now = str(time.time()) m = hashlib.md5() m.update(bytes(now,encoding=‘utf-8‘)) return m.hexdigest() def __setitem__(self, key, value): # print(key,value) # key 就是用戶自己設置session[‘uuuu‘]=‘root‘中的uuuu,value就是root self.ppp.set(self.random_str, key, value) print(‘1‘,container) def __getitem__(self, item): # print(item) # uuuu # print(‘getitem‘,container) print(‘2‘,container) return self.ppp.get(self.random_str,item) def __delitem__(self, key): self.ppp.delete(self.random_str,key) def open(self): pass def cloes(self): pass class Foo(object): def initialize(self): # print(self) # <__main__.LoginHandler object at 0x00000000038702E8> self.session = Session(self) # 傳入Session的self就是調用者,誰調用Session誰就是self super(Foo, self).initialize() # 執行RequestHandler中的initialize class HomeHandler(Foo,tornado.web.RequestHandler): def get(self): user = self.session[‘uuuu‘] # 調用Session類中的__getitem__方法, 獲取value print(‘user‘,user) if not user: self.write(‘不是合法登錄‘) else: self.write(user) print(‘哈哈哈測試成功,刪除啦‘) del self.session[‘uuuu‘] print(container) class LoginHandler(Foo,tornado.web.RequestHandler): def get(self): # self.session[‘uuuu‘] # 調用Session類中的__getitem__方法, 獲取value # del self.session[‘uuuu‘] # 調用Session類中的__delitem__方法, 刪除 self.session[‘uuuu‘] = "root" # 調用Session類中的__setitem__方法,在session裏面設置了uuuu self.write("Hello, world") # print(container) self.redirect(‘/home‘) application = tornado.web.Application([ # (r"/index", MainHandler), (r"/login", LoginHandler), (r"/home", HomeHandler), ]) if __name__ == "__main__": application.listen(9999) tornado.ioloop.IOLoop.instance().start()Version 2
Tronado自定義Session