给 tornado 加装 session 轮子
【摘要】 tornado 是一个非常流行的 web framework,也是一个自带 IO 的 web server,而它作为 web server 采用的是 asynchronous IO 的网络模型,这是一种很高效的模型。网上有很多 tornado 与其他 web 框架的性能比较,其实,它们根本不是一个层次的东西,因为在所有的比较对象中,只有 tornado 同时具备 IO ...
tornado 是一个非常流行的 web framework,也是一个自带 IO 的 web server,而它作为 web server 采用的是 asynchronous IO 的网络模型,这是一种很高效的模型。网上有很多 tornado 与其他 web 框架的性能比较,其实,它们根本不是一个层次的东西,因为在所有的比较对象中,只有 tornado 同时具备 IO / web server / web framework,并且做到了极致。
开发 web 项目,我一般会首选 tornado 。喜欢 tornado,不是因为它全能,而是因为它简洁。简洁到什么程度呢?作为 web 框架,它连 session 都没有。但是,正是这种简洁,降低了学习成本,给用户提供了无限的开发空间。
为 tornado 增加 session 机制,基本思路就是从 tornado.web.RequestHandler 派生新类,重写 initialize() 方法。当类实例被构造函数创建后,会先运行该方法。我们定义 initialize() 方法读取名为 session_id 的 cookie,如果存在,则读取以 session_id 命名的 session 文件,取得 session 内容,否则,session 为空。
闲言少叙,直接上代码。这段代码在 py2 环境 tornado 2.x 以后的各种版本下都可运行。
# -*- coding: utf-8 -*-
# Tornado Session For py2
#---------------------------------------
# version 3.2 / Update: 2018-12-24
#
# 1. 重写get_current_user方法,读取session_id
# version 3.1 / Update: 2018-12-21
#
# 1. 以文件作为session的后端
# 2. 私有方法命名规范化
# version 3.0 / Update: 2018-12-19
#
# 1. 以cookie形式实现session
# 2. 用装饰器引入db
# 3. 类方法命名规范化(不兼容之前的版本)
import os, time
import hashlib
import json
import tornado.web
class SessionRH(tornado.web.RequestHandler): """为RequestHandler增加session机制""" def initialize(self): """初始化(构造函数完成之后)""" self._init_session() def _init_session(self): """session初始化""" self.session = dict() self.session_id = self.get_secure_cookie('session_id') if self.session_id: session_file = os.path.join(self.application.settings["session_path"], self.session_id) if os.path.isfile(session_file): with open(session_file, 'r') as fp: self.session.update(json.loads(fp.read().strip())) if not self.session: self.session_id = None self.clear_cookie('session_id') def _save_session(self): """保存session""" try: expiry = self.application.settings["session_expiry"] except: expiry = 0 if not expiry: expiry = None self.set_secure_cookie('session_id', self.session_id, expires_days=expiry) with open(os.path.join(self.application.settings["session_path"], self.session_id), 'w') as fp: fp.write(json.dumps(self.session)) def create_session(self, **kwargs): """生成唯一的session_id及其它需要保存的数据项""" rand = os.urandom(16) now = time.time() self.session_id = hashlib.sha1("%s%s%s" %(rand, now, self.request.remote_ip)).hexdigest() self.session.update(kwargs) self.session.update({'last_active':str(now)}) self._save_session() def destroy_session(self): """注销session""" session_file = os.path.join(self.application.settings["session_path"], self.session_id) if os.path.isfile(session_file): os.remove(session_file) self.session_id = None self.session = dict() self.clear_cookie('session_id') def append_session_item(self, **kwargs): """追加session项""" self.session.update(kwargs) self._save_session() def delete_session_item(self, name): """删除session项""" if name in self.session: self.session.pop(name) self._save_session() def get_current_user(self): """重写get_current_user方法,读取session_id""" return self.get_secure_cookie("session_id") @property def db(self): """用装饰器引入db(application.db)""" return self.application.db if __name__ == '__main__': pass
文章来源: xufive.blog.csdn.net,作者:天元浪子,版权归原作者所有,如需转载,请联系作者。
原文链接:xufive.blog.csdn.net/article/details/85098740
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)