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()

 

posted @ 2019-01-06 23:40  心灵蚂蚁  阅读(1954)  评论(0编辑  收藏  举报