自制session

 

原理

一、面向對象中經過索引的方式訪問對象,須要內部實現 __getitem__ 、__delitem__、__setitem__方法

二、Tornado框架中,默認執行Handler的get/post等方法以前默認會執行 initialize方法,因此能夠經過自定義的方式使得全部請求在處理前執行操做...

三、session其實就是定義在服務器端用於保存用戶回話的容器,其必須依賴cookie才能實現。

四、工廠模式,此非必須

示例

# -*- 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
相關文章
相關標籤/搜索