自制session

 

原理

1、面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ 、__delitem__、__setitem__方法

2、Tornado框架中,默认执行Handler的get/post等方法之前默认会执行 initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作...

3、session其实就是定义在服务器端用于保存用户回话的容器,其必须依赖cookie才能实现。

4、工厂模式,此非必须

示例

# -*- coding:utf-8 -*-

# SESSION_ENGINE = "session_code.RedisSession"
SESSION_ENGINE = "session_code.CacheSession"
SESSION_ID = "__session_id__"
EXPIRES = 300


REDIS_HOST = '192.168.11.96'
REDIS_PORT = 6379
settings.py
# -*- coding:utf-8 -*-
# 1. "scrapy.middlware.C1"
# import importlib
# path = "scrapy.middlware.C1"
# md,cls = path.rsplit('.',maxsplit=1)
# m = importlib.import_module(md)
# getattr(m,cls)
# 2. 面向对象

# class Foo(object):
#
#     def __getitem__(self, item):
#         return "123"
#
#     def __setitem__(self, key, value):
#         pass
#
#     def __delitem__(self, key):
#         pass
# obj = Foo()
# v = obj['k1']
# print(v)
# obj['k1'] = 666
# del obj['k1']

# request.session['k1'] = 666

# 3.
import time
import hashlib
from . import settings

def gen_random_str():

    md5 = hashlib.md5()
    md5.update(str(time.time()).encode('utf-8'))
    return md5.hexdigest()

class CacheSession(object):

    container = {}

    def __init__(self,handler):
        self.handler = handler
        self.session_id = settings.SESSION_ID
        self.expires = settings.EXPIRES
        self.initial()

    def initial(self):
        client_random_str = self.handler.get_cookie(self.session_id)
        if client_random_str and client_random_str in self.container:
            self.random_str = client_random_str
        else:
            self.random_str = gen_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):
        return self.container[self.random_str].get(item)

    def __setitem__(self, key, value):

        self.container[self.random_str][key] = value

    def __delitem__(self, key):
        if key in self.container[self.random_str]:
            del self.container[self.random_str][key]

class RedisSession(object):
    def __init__(self,handler):
        self.handler = handler
        self.session_id = settings.SESSION_ID
        self.expires = settings.EXPIRES
        self.initial()
    @property
    def conn(self):
        import redis
        conn = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT)
        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 = gen_random_str()

        expires = time.time()+ self.expires
        self.handler.set_cookie(self.session_id,self.random_str,expires=expires)
        self.conn.expire(self.random_str,self.expires)

    def __getitem__(self, item):
        import json
        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):
        import json
        self.conn.hset(self.random_str,key,json.dumps(value))

    def __delitem__(self, key):
        self.conn.hdel(self.random_str,key)

class SessionFactory(object):
    @staticmethod
    def get_session():
        from . 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
mysession.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from tornado.web import RequestHandler
from .mysession import SessionFactory


class SessionHandler(object):
    def initialize(self, *args, **kwargs):
        cls = SessionFactory.get_session()
        self.session = cls(self)  # CacheSession对象,RedisSession对象


class LoginHandler(SessionHandler,RequestHandler):
    # def initialize(self,*args,**kwargs):
    #     cls = SessionFactory.get_session()
    #     self.session = cls(self)  # CacheSession对象,RedisSession对象
    #     print(self.session.container)

    def get(self):
        self.render("login.html")

    def post(self, *args, **kwargs):
        user = self.get_argument("user")
        pwd = self.get_argument("pwd")
        if user == "alex" and pwd == "123":
            self.session["user"] = user
            self.redirect("/index")
        else:
            self.render("login.html")

class IndexHandler(SessionHandler,RequestHandler):
    # def initialize(self,*args,**kwargs):
    #     cls = SessionFactory.get_session()
    #     self.session = cls(self)  # CacheSession对象,RedisSession对象
    #     # print(self.session.container)

    def get(self,*args,**kwargs):
        user = self.session["user"]
        print(user)
        if user:
            self.write("welcome index")
        else:
            self.redirect("/login")

sett = {
    "template_path": "views",
}
application = tornado.web.Application([
    (r"/login", LoginHandler),
    (r"/index", IndexHandler),
],**sett)

# application.reverse_url("n1")

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
tornado_app.py

 

1def gen_random_str():   # 这个是为了生成随机字符串for session_id
    md5 = hashlib.md5()
    md5.update(str(time.time()).encode("utf-8"))
    return md5.hexdigest()



2、
create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest()


以上均可
补充:random_str

 

posted @ 2018-08-31 11:47  fat39  阅读(163)  评论(0编辑  收藏  举报