自制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 == "":
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
1、
def 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
自制session的更多相关文章
- Tornado之笔记集合
目录 一.基本使用 二.路由系统 三.视图函数 四.模版语言 五.cookie 六.CSRF 七.文件上传 八.异步非阻塞 九.RESTFUL 十.自定义组件 一.基本使用 1.最简使用 import ...
- 「七天自制PHP框架」第三天:PHP实现的设计模式
往期回顾:「七天自制PHP框架」第二天:模型与数据库,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 为什么要使用设计模 ...
- netcore的Session使用小记
之前说过,core需要什么功能就添加并使用什么中间件 照例,在Startup.cs的ConfigureServices方法中添加services.AddSession();再在Configure方法中 ...
- 自制MVC框架原理介绍
当初用jsp开发程序时,因为很多东西写在一起混淆的,项目做大或者变更的时候就会很吃力,联动性太大,有时修改视图的东西都可能会影响业务逻辑,分层不明确. 后来听说了Struts MVC,做过几个示例,层 ...
- session实现购物车
为实现简单的购物功能(购物车添加.账户查看.购物车商品删除.实时的购物商品数量及价格的计算显示.购物车商品数量可手动输入等),用session实现了一简单的以php语言为基础.连接MySQL数据库的购 ...
- Asp.net Core中使用Session
前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...
- 懒加载session 无法打开 no session or session was closed 解决办法(完美解决)
首先说明一下,hibernate的延迟加载特性(lazy).所谓的延迟加载就是当真正需要查询数据时才执行数据加载操作.因为hibernate当中支持实体对象,外键会与实体对象关联起来.如 ...
- 探索ASP.NET MVC5系列之~~~6.Session篇(进程外Session)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- Nhibernate的Session管理
参考:http://www.cnblogs.com/renrenqq/archive/2006/08/04/467688.html 但这个方法还不能解决Session缓存问题,由于创建Session需 ...
随机推荐
- Python自动化之modelform和原生ajax
modelform验证 `views.py` from django.shortcuts import render,HttpResponse from app01 import models fro ...
- active developer path ("/Applications/Xcode.app/Contents/Developer")
-> git xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer" ...
- js判断设备信息,安卓、ios、还是pc端
前端开发获取设备信息的代码if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { window.location.href =" ...
- Ext4文件系统架构分析(二)
接着上一篇博文,继续分析Ext4磁盘布局中的元数据. 1.7 超级块 超级块记录整个文件系统的大量信息,如数据块个数.inode个数.支持的特性.管理信息,等待. 如果设置sparse_super特性 ...
- 什么是X86和X86-64
X86的定义 X86是一个Intel或AMD通用计算机系列的标准编号缩写,也是32位微处理器架构的一种,也标识一套通用的计算机指令集. X86-64的定义 X86-64,简称X64,是一个Intel或 ...
- 面向对象之static关键字
static概念 static它是静态修饰符,一般用来修饰类中的成员. static特点 1.多个对象共享一个static成员变量.一个对象将static成员变量值修改了,其他对象中的static成员 ...
- to improve sqlite performance
INSERT is really slow - I can only do few dozen INSERTs per second http://www.sqlite.org/faq.html#q1 ...
- 百度地图API和高德地图API资料集锦
[高德地图API]从零开始学高德JS API(五)路线规划——驾车|公交|步行 [高德地图API]从零开始学高德JS API(四)搜索服务——POI搜索|自动完成|输入提示|行政区域|交叉路口|自 ...
- zookeeper入门实例
package org.merit.test.zookeepertest; import java.io.IOException;import java.util.List;import java.u ...
- Flash Player调试器版本的解决办法Flash Builder 找不到所需的Adobe
Flash Player调试器版本的解决办法Flash Builder 找不到所需的Adobe Flash Builder在Debug时出现的问题:Flash Builder 找不到所需的Adob ...