[albatross-users] Change to handling of expired sessions

Andrew McNamara andrewm at object-craft.com.au
Wed Feb 2 12:40:52 EST 2011


Handling of expired sessions has been a common source of grief. Partly
this was because Albatross didn't make it easy to do something with
the SessionExpired exception, but also an incompatibility between the
default exception handling and the cookie based sessions resulted in a
SessionExpired loop.

To address this, I have changed the Application.run() method to catch
SessionExpired exceptions, and call a new application handle_session_expired()
method. The new method renders a session_expired.html template if you supply
it, falling back to a "your session has expired" HTML message if not. This
also addresses the SessionExpired loop problem as a side effect.

The SessionExpired loop problem occurred because the SessionFileContextMixin
and SessionServerContextMixin relied on being able to clear the session
cookie, but this only happens if the response to the browser occurs via
the application context; the handle_exception() method either uses a fresh
context, or responds directly via the request object, so the cookie was
never cleared.

This change will appear in the next Albatross release (no due date, yet),
so if you have any comments or suggestions, let me know. You may also
need to change your expired session handling in existing applications
when you adopt this version, although methods that relied on overloading
load_session() and catching the SessionExpired exception there will
continue to work.

Index: albatross/app.py
===================================================================
--- albatross/app.py	(revision 16709)
+++ albatross/app.py	(revision 16710)
@@ -13,6 +13,7 @@
 from albatross.context import NamespaceMixin, ExecuteMixin, ResourceMixin,\
      _caller_globals
 
+from albatross.template import Template
 from albatross import tags
 
 from albatross.common import *
@@ -283,6 +284,8 @@
         except Redirect, e:
             self.save_session(ctx)
             ctx.send_redirect(e.loc)
+        except SessionExpired:
+            self.handle_session_expired(ctx, req)
         except:
             self.handle_exception(ctx, req)
         return req.return_code()
@@ -305,6 +308,24 @@
             del etype, value, tb
         return pyexc, htmlexc
 
+    def handle_session_expired(self, ctx, req):
+        try:
+            templ = self.load_template('session_expired.html')
+        except TemplateLoadError:
+            templ = Template(ctx, '<internal>',
+'''<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<html>
+ <head>
+  <title>Session has expired</title>
+ </head>
+ <body>
+  <h1>Your session has expired</h1>
+ </body>
+</html>
+''')
+        templ.to_html(ctx)
+        ctx.flush_content()
+
     def handle_exception(self, ctx, req):
         pyexc, htmlexc = self.format_exception()
         req.set_status(HTTP_INTERNAL_SERVER_ERROR)

-- 
Andrew McNamara, Senior Developer, Object Craft
http://www.object-craft.com.au/



More information about the Albatross-users mailing list