In
webapp2, sessions by default is stored in cookies.
A documentation about it can be found here:
http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html
A problem I'm encountering when storing session information in cookies, is that there seem to be a size limit of the amount of data you can store in a cookie. What happens then, is I lost my session information, and the data that I wanted to save the session is not being saved properly.
Luckily, webapp2 allows us to save sessions in two other forms: memcache and datastore (using ndb).
This is great. So then I tried to change the session configuration to have it stored in datastore, and see if it will solve my problem with large data size.
In this post I will guide you step by step on how to configure your webapp2 application to use the datastore as the session backend.
First, let's start from the top of the documentation on how to set up sessions in webapp2 using the default cookie backend:
You will create a BaseHandler and a dispatch method that creates the session store.
import webapp2
from webapp2_extras import sessions
class BaseHandler(webapp2.RequestHandler):
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
@webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
You will also need to create a configuration dict to be pass in to your app that defines the session secret key.
config = {}
config['webapp2_extras.sessions'] = {
'secret_key': 'my-super-secret-key',
}
app = webapp2.WSGIApplication([
('/', HomeHandler),
], config=config)
When these has been set up you can start using your sessions as follows:
# To set a value:
self.session['foo'] = 'bar'
# To get a value:
foo = self.session.get('foo')
Now, we want to use the datastore as the session backend instead of the cookie.
We'll have to modify the configuration dictionary, adding the backends dictionary :
config['webapp2_extras.sessions'] = {
'secret_key': 'my-super-secret-key',
'backends': {'datastore': 'webapp2_extras.appengine.sessions_ndb.DatastoreSessionFactory',
'memcache': 'webapp2_extras.appengine.sessions_memcache.MemcacheSessionFactory',
'securecookie': 'webapp2_extras.sessions.SecureCookieSessionFactory'
}
Next, we need to modify the session provider, specifying the backend that you wanted:
@webapp2.cached_property
def session(self):
# Returns a session using the datastore backend.
return self.session_store.get_session(backend='datastore')
And that's all you need to do! Now whenever you save a session, you will see a new Session entity in your AppEngine datastore.
After storing my sessions in the datatsore instead of cookie, my problem with sessions with large amount of data was resolved. So indeed there was some kind of limit when storing your session data in cookies.
I would recommend using the datastore or memcache to store your session for a few reasons.
1. If you have sensitive information to be stored, (e.g. email addresses, phone number), it will be more secure to store it in datastore than the browser's cookie.
2. Cookie is set on domain level. Depends on how your app is set up, you could encounter session issues when navigating among different domains.
3. The most important point. In webapp2, cookie expiry is set using the max-age parameter, and this parameter
is not supported in IE browsers. So if you ever want to persist the session even after browser is closed, it will just not work in IE. And since
IE is still one of the major browsers nowadays, you really should care about it.