Here is a very basic class for handling sessions on App Engine:
"""Lightweight implementation of cookie-based sessions for Google App Engine.
Classes:
Session
"""
import os
import random
import Cookie
from google.appengine.api import memcache
_COOKIE_NAME = 'app-sid'
_COOKIE_PATH = '/'
_SESSION_EXPIRE_TIME = 180 * 60
class Session(object):
"""Cookie-based session implementation using Memcached."""
def __init__(self):
self.sid = None
self.key = None
self.session = None
cookie_str = os.environ.get('HTTP_COOKIE', '')
self.cookie = Cookie.SimpleCookie()
self.cookie.load(cookie_str)
if self.cookie.get(_COOKIE_NAME):
self.sid = self.cookie[_COOKIE_NAME].value
self.key = 'session-' + self.sid
self.session = memcache.get(self.key)
if self.session:
self._update_memcache()
else:
self.sid = str(random.random())[5:] + str(random.random())[5:]
self.key = 'session-' + self.sid
self.session = dict()
memcache.add(self.key, self.session, _SESSION_EXPIRE_TIME)
self.cookie[_COOKIE_NAME] = self.sid
self.cookie[_COOKIE_NAME]['path'] = _COOKIE_PATH
print self.cookie
def __len__(self):
return len(self.session)
def __getitem__(self, key):
if key in self.session:
return self.session[key]
raise KeyError(str(key))
def __setitem__(self, key, value):
self.session[key] = value
self._update_memcache()
def __delitem__(self, key):
if key in self.session:
del self.session[key]
self._update_memcache()
return None
raise KeyError(str(key))
def __contains__(self, item):
try:
i = self.__getitem__(item)
except KeyError:
return False
return True
def _update_memcache(self):
memcache.replace(self.key, self.session, _SESSION_EXPIRE_TIME)
I would like some advices on how to improve the code for better security.
Note: In the production version it will also save a copy of the session in the datastore.
Note’: I know there are much more complete implementations available online though I would like to learn more about this subject so please don’t answer the question with “use that” or “use the other” library.
Here is a suggestion for simplifying your implementation.
You are creating a randomized temporary key that you use as the session’s key in the memcache. You note that you will be storing the session in the datastore as well (where it will have another key).
Why not randomize the session’s datastore key, and then use that as the one and only key, for both the database and the memcache (if necessary)? Does this simplification introduce any new security issues?
Here’s some code for creating a randomized datastore key for the Session model:
To get the ID from the session (i.e. to store in the cookie) use:
To retrieve the session instance after the ‘sid’ has been read from the cookie: