zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    单例类
    日期类2
    日历类
    日期转换类
    抓取网页内容并截图
    关于计时器与多线程
    让页面上图片不变形
    Thread 调用方法的方式
    语音放大缩小
    阻止Enter键回发到服务端Asp.net
  • 原文地址:https://www.cnblogs.com/linyuhong/p/10231050.html
Copyright © 2011-2022 走看看