1. 程式人生 > >Tornado之Session實現

Tornado之Session實現

Tornado框架中,預設執行Handler的get/post等方法之前預設會執行 initialize方法,所以可以通過自定義的方式使得所有請求在處理前執行操作

import tornado.ioloop
import tornado.web

import time
import hashlib


# 將session_id儲存在記憶體中
class Cache(object):
    def __init__(self):
        self.container = dict()

    def __contains__(self, item):
        
return item in self.container def initial(self,random_str): self.container[random_str] = dict() def get(self,random_str,key): return self.container[random_str].get(key) def set(self,random_str,key,value): self.container[random_str][key] = value
def delete(self,random_str,key): del self.container[random_str][key] def open(self): pass def close(self): pass def clear(self,random_str): del self.container[random_str] db = Cache # 這裡的Cache可以換成任何其他想要的Session儲存方式,這裡為了演示方便就直接儲存在記憶體中了
class Session(object): def __init__(self, handler): self.handler = handler self.random_str = None self.db = db() # 去使用者請求資訊中獲取session_id,如果沒有,表示是新使用者 client_random_str = self.handler.get_cookie("session_id") if not client_random_str: # 新使用者 self.random_str = self.create_random_str() self.db.initial(self.random_str) else: # 檢查隨機字串是否在字典中,防止使用者自己偽造session_id值 if client_random_str in self.db: # 老使用者 self.random_str = client_random_str else: # 非法使用者 重新為其賦值 self.random_str = self.create_random_str() self.db.initial(self.random_str) ctime = time.time() # 往客戶端瀏覽器設定session_id self.handler.set_cookie("session_id", self.random_str, expires=ctime+1800) def create_random_str(self): value = str(time.time()) m = hashlib.md5() m.update(bytes(value, encoding="utf-8")) return m.hexdigest() def __setitem__(self, key, value): self.db.set(self.random_str, key, value) def __getitem__(self, key): return self.db.get(self.random_str, key) def __delitem__(self, key): self.db.delete(self.random_str, key) def clear(self): self.db.clear(self.random_str) class Foo(object): def initialize(self): self.session = Session(self) # 這裡是一個重點,Foo作為HomeHandler的父類,因此這裡的"self"就是HomeHandler的物件,所以可以呼叫"self.set_cookie()",把 super(Foo, self).initialize() # "self"傳遞給Session(),通過"handler"接收,這樣就可以在Session()中呼叫"self.set_cookie()"了 class LoginHandler(Foo, tornado.web.RequestHandler): def get(self): self.session["user"] = "root" # 為了演示方便,這裡就不去資料庫查詢使用者名稱和密碼了,直接賦值 self.redirect("/home") class HomeHandler(Foo, tornado.web.RequestHandler): def get(self): user = self.session["user"] if not user: self.redirect("https://www.biying.com") self.write("歡迎登陸:" + user) class MainHandler(Foo, tornado.web.RequestHandler): def get(self): # self.write("Hello, world") self.render("main.html") settings = { "template_path":"views", } application = tornado.web.Application([ (r"/index", MainHandler), (r"/login", LoginHandler), (r"/home", HomeHandler), ], **settings) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()