Flask by default uses the Werkzeug provided 'secure cookie' as session system. It works by pickling the session data, compressing it and base64 encoding it.
This was a reasonable decision at the time but now there are better modules available and if you are fine with another external dependency you could start using itsdangerous instead of the secure cookie which works the same but has a couple of advantages:
Starting with Flask 0.8 adding support is easy due to the newly introduced session interface:
from werkzeug.datastructures import CallbackDict from flask.sessions import SessionInterface, SessionMixin from itsdangerous import URLSafeTimedSerializer, BadSignature class ItsdangerousSession(CallbackDict, SessionMixin): def __init__(self, initial=None): def on_update(self): self.modified = True CallbackDict.__init__(self, initial, on_update) self.modified = False class ItsdangerousSessionInterface(SessionInterface): salt = 'cookie-session' session_class = ItsdangerousSession def get_serializer(self, app): if not app.secret_key: return None return URLSafeTimedSerializer(app.secret_key, salt=self.salt) def open_session(self, app, request): s = self.get_serializer(app) if s is None: return None val = request.cookies.get(app.session_cookie_name) if not val: return self.session_class() max_age = app.permanent_session_lifetime.total_seconds() try: data = s.loads(val, max_age=max_age) return self.session_class(data) except BadSignature: return self.session_class() def save_session(self, app, session, response): domain = self.get_cookie_domain(app) if not session: if session.modified: response.delete_cookie(app.session_cookie_name, domain=domain) return expires = self.get_expiration_time(app, session) val = self.get_serializer(app).dumps(dict(session)) response.set_cookie(app.session_cookie_name, val, expires=expires, httponly=True, domain=domain)
To activate this session interface all you have to do is to change the
session_interface attribute on your application:
app.session_interface = ItsdangerousSessionInterface()
This snippet by Armin Ronacher can be used freely for anything you like. Consider it public domain.