#395 closed defect (fixed)
[patch] New session middleware for browser-session length cookies
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Core (Other) | Version: | |
Severity: | blocker | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I noticed that the [source:/django/trunk/django/middleware/sessions.py SessionsMiddleware] class was setting a cookie with an explicit expiration date. So I created this modified middleware for my application that allows SESSION_COOKIE_AGE
to be set to None
(which then creates a session cookie with no expiration date, meaning the cookie will be deleted when the browser session ends).
Currently the middleware sets the session expiration date in the database to 1 hour from when the session cookie is set, but this could be changed with a configuration variable (SESSION_EXPIRATION_AGE
, perhaps?).
from django.middleware import sessions as sessionsMiddleware from django.conf.settings import SESSION_COOKIE_NAME, SESSION_COOKIE_AGE, SESSION_COOKIE_DOMAIN from django.models.core import sessions import datetime class SingleSessionMiddleware(sessionsMiddleware.SessionMiddleware): def process_response(self, request, response): try: modified = request.session.modified except AttributeError: modified = False if modified: session_key = request.session.session_key or sessions.get_new_session_key() if SESSION_COOKIE_AGE != None: new_session = sessions.save(session_key, request.session._session, datetime.datetime.now() + datetime.timedelta(seconds=SESSION_COOKIE_AGE)) else: # right now I'm just making sessions last for an hour ... should # probably make a configuration directive to specify the seconds # till the session expires new_session = sessions.save(session_key, request.session._session, datetime.datetime.now() + datetime.timedelta(hours=1)) # TODO: Accept variable session length and domain. response.set_cookie(SESSION_COOKIE_NAME, session_key, max_age=SESSION_COOKIE_AGE, domain=SESSION_COOKIE_DOMAIN) return response
Change History (5)
comment:1 by , 19 years ago
comment:2 by , 19 years ago
Status: | new → assigned |
---|
comment:3 by , 19 years ago
So I got this working with the lastest Django SVN. Here's the middleware class I used:
from django.conf.settings import SESSION_COOKIE_NAME, SESSION_COOKIE_AGE, SESSION_COOKIE_DOMAIN, SESSION_SAVE_EVERY_REQUEST from django.models.core import sessions from django.utils.cache import patch_vary_headers from django.middleware import sessions as sessionsMiddleware import datetime class SingleSessionMiddleware(sessionsMiddleware.SessionMiddleware): def process_response(self, request, response): # If request.session was modified, or if response.session was set, save # those changes and set a session cookie. patch_vary_headers(response, ('Cookie',)) try: modified = request.session.modified except AttributeError: pass else: if modified or SESSION_SAVE_EVERY_REQUEST: session_key = request.session.session_key or sessions.get_new_session_key() if SESSION_COOKIE_AGE != None: new_session = sessions.save(session_key, request.session._session, datetime.datetime.now() + datetime.timedelta(seconds=SESSION_COOKIE_AGE)) expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT") response.set_cookie(SESSION_COOKIE_NAME, session_key, max_age=SESSION_COOKIE_AGE, expires=expires, domain=SESSION_COOKIE_DOMAIN) else: new_session = sessions.save(session_key, request.session._session, datetime.datetime.now() + datetime.timedelta(hours=1)) response.set_cookie(SESSION_COOKIE_NAME, session_key, max_age=SESSION_COOKIE_AGE, domain=SESSION_COOKIE_DOMAIN) return response
comment:4 by , 19 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:5 by , 19 years ago
priority: | normal → highest |
---|---|
Severity: | normal → blocker |
Type: | enhancement → defect |
I just noticed one downside to this code (assuming you set SESSION_COOKIE_AGE=None in settings/main.py): the admin still uses the basic django session code which doesn't like None...
Placing
SESSION_COOKIE_AGE=60 * 60 * 24 * 7 * 2
in the settings/admin.py fixes the problem, but I thought this was an appropriate issue to add to the ticket.