public
Last active

Tornado session manager use redis

  • Download Gist
app.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Application(tornado.web.Application):
def __init__(self):
tornado.web.Application.__init__(self, handlers, **settings)
self.db_session = db_session
self.redis = redis.StrictRedis()
self.session_store = RedisSessionStore(self.redis)
 
 
 
class BaseHandler(tornado.web.RequestHandler):
 
def get_current_user(self):
return self.session['user'] if self.session and 'user' in self.session else None
 
@property
def session(self):
sessionid = self.get_secure_cookie('sid')
return Session(self.application.session_store, sessionid)
session.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
import cPickle as pickle
from uuid import uuid4
import time
 
 
class RedisSessionStore:
 
def __init__(self, redis_connection, **options):
self.options = {
'key_prefix': 'session',
'expire': 7200,
}
self.options.update(options)
self.redis = redis_connection
 
def prefixed(self, sid):
return '%s:%s' % (self.options['key_prefix'], sid)
 
def generate_sid(self, ):
return uuid4().get_hex()
 
def get_session(self, sid, name):
data = self.redis.hget(self.prefixed(sid), name)
session = pickle.loads(data) if data else dict()
return session
 
def set_session(self, sid, session_data, name):
expiry = self.options['expire']
self.redis.hset(self.prefixed(sid), name, pickle.dumps(session_data))
if expiry:
self.redis.expire(self.prefixed(sid), expiry)
 
def delete_session(self, sid):
self.redis.delete(self.prefixed(sid))
 
 
class Session:
 
def __init__(self, session_store, sessionid=None):
self._store = session_store
self._sessionid = sessionid if sessionid else self._store.generate_sid()
self._sessiondata = self._store.get_session(self._sessionid, 'data')
self.dirty = False
 
def clear(self):
self._store.delete_session(self._sessionid)
 
def access(self, remote_ip):
access_info = {'remote_ip':remote_ip, 'time':'%.6f' % time.time()}
self._store.set_session(
self._sessionid,
'last_access',
pickle.dumps(access_info)
)
 
def last_access(self):
access_info = self._store.get_session(self._sessionid, 'last_access')
return pickle.loads(access_info)
 
@property
def sessionid(self):
return self._sessionid
 
def __getitem__(self, key):
return self._sessiondata[key]
 
def __setitem__(self, key, value):
self._sessiondata[key] = value
self._dirty()
 
def __delitem__(self, key):
del self._sessiondata[key]
self._dirty()
 
def __len__(self):
return len(self._sessiondata)
 
def __contains__(self, key):
return key in self._sessiondata
 
def __iter__(self):
for key in self._sessiondata:
yield key
 
def __repr__(self):
return self._sessiondata.__repr__()
 
def __del__(self):
if self.dirty:
self._save()
 
def _dirty(self):
self.dirty = True
 
def _save(self):
self._store.set_session(self._sessionid, self._sessiondata, 'data')
self.dirty = False

How would I use this if I did not want to use cookies? Say I store a token in localStorage. Would there be security issues?

No where in the code does it set_secure_cookie('sid', sessionid) if the get_secure_cookie returns None? Should it?

set_secure_cookie will be done in the login handler...

Apologies if I'm missing something obvious, but where does the db_session from the self.db_session = db_session line come from?

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.