cookie与session,以及tornado中session的实现

一.cookie

在需要用户验证的web程序中,每一次用户发起请求,都需要对请求用户进行认证。那么在用户第一次向服务器发起请求时,服务器向用户发送一系列唯一标识该用户的键值对,,称为cookie,这些键值对可以是一个随机生成的字符串也可以是一些用户的信息,比如用户名,年龄,性别等等,那么接下来用户用服务器发送请求时都必须带着cookie,这样服务器会对cookie进行验证。

服务器端可以通过以下方式对cookie进行操作:

  • self.cookies:获取所有cookie键值对
  • self.set_cookie():设置cookie
  • self.get_cookie():根据键获取cookie值

在前端可以通过javascript对cookie进行操作:

  • document.cookie:获取全部cookie(字符串形式)
  • document.cookie="key=value":添加cookie
  • document.cookie="key=value;path='/', expires=7":每设置一个cookie,同时也可以对它的超时时间expires,访问路径path等等作一些设置

在前端也可以通过JQuery的一个插件JQuery cookie对cookie进行操作。

二.session

cookie是保存在客户端(浏览器)的用户信息,每次发起请求都需要携带,当用户的信息很大,并且有需要保密的信息时,将cookie放在网络上传输就会有安全性降低、占用数据流量的缺点,那么session就可以用来解决这个问题。 session不会把所有用户信息作为cookie传送给用户,session会通过各种手段(例如对当前时间进行md5加密生成一串随机的字符串)生成一个字符串作为发送给用户的cookie,而其他的用户信息用一个字典保存在服务器端。其数据保存结构如下所示:大字典的键作为cookie发送给用户,大字典的值作为用户信息保存在服务器端。

{
    '用户1的唯一标识字符串': {"k1": 'v1', 'k2': 'v2'},
    '用户2的唯一标识字符串': {"k1": 'v1', 'k2': 'v2'},
    '用户3的唯一标识字符串': {"k1": 'v1', 'k2': 'v2'},
}

tornado对cookie的操作作了一些封装,可以直接像第1节中介绍的那样对cookie进行操作,但是tornado中并没有对session进行封装,接下来介绍自己封装的session。

三.tornado中Session的实现

#大字典
container = {}


class Session():
    def __init__(self, handler):
        self.handler = handler
        self.random_str = None

    def __generate_random_str(self):
        """
        生成用户的唯一标识字符串
        :return:
        """
        import hashlib
        import time
        obj = hashlib.md5()
        obj.update(bytes(str(time.time()), 'utf-8'))
        random_str = obj.hexdigest()
        return random_str

    def __setitem__(self, key, value):
        """
        生成cookie并以键值对形式设置用户信息
        :param key: 键
        :param value: 值
        :return: 
        """
        # 在container中加入随机字符串
        if not self.random_str:
            random_str = self.handler.get_cookie('__session')
            if not random_str:
                random_str = self.__generate_random_str()
                # 定义专属于自己的数据
                container[random_str] = {}
            else:
                if random_str in container.keys():
                    pass
                else:
                    random_str = self.__generate_random_str()
                    # 定义专属于自己的数据
                    container[random_str] = {}
            self.random_str = random_str
        container[self.random_str][key] = value
        # 在客户端写入随机字符串
        self.handler.set_cookie('__session', self.random_str)

    def __getitem__(self, key):
        """
        根据键获取session中的用户信息
        :param key: 
        :return: 
        """
        # 从客户端获取的唯一标识字符串cookie
        random_str = self.handler.get_cookie('__session')
        if not random_str:
            return None
        else:
            # 从container中获取专属于自己的数据
            user_info = container.get(random_str, None)
            if not user_info:
                return None
            else:
                value = user_info.get(key, None)
                return value

接下来,可以:

  • 通过obj=Session(handler)初始化一个session对象
  • 通过obj[key]获取键为key的session值
  • 通过obj[key,value]设置cookie

你可能感兴趣的:(黑历史18-19)