diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-08-21 13:54:53 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-08-21 13:54:53 +0000 |
| commit | c8c159cbbad71deb4d13d6b4e10d4f38817ebdc4 (patch) | |
| tree | 73ec8883d3f4869125bda610e425158a597dc43e | |
| parent | 2f7d62439153b97033960141518b6b8cf1512756 (diff) | |
When logging in, change the session key whilst preserving any existing
sesssion. This means the user will see their session preserved across a login
boundary, but somebody snooping the anonymous session key won't be able to view
the authenticated session data.
This is the final piece of the session key handling changes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8459 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/contrib/auth/__init__.py | 13 | ||||
| -rw-r--r-- | django/contrib/sessions/backends/base.py | 10 | ||||
| -rw-r--r-- | django/contrib/sessions/tests.py | 29 |
3 files changed, 48 insertions, 4 deletions
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index e73e34b816..87c2bc1b50 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -53,10 +53,15 @@ def login(request, user): # TODO: It would be nice to support different login methods, like signed cookies. user.last_login = datetime.datetime.now() user.save() - if request.session.get('SESSION_KEY', user.id) != user.id: - # To avoid reusing another user's session, create a new, empty session - # if the existing session corresponds to a different authenticated user. - request.session.flush() + + if SESSION_KEY in request.session: + if request.session[SESSION_KEY] != user.id: + # To avoid reusing another user's session, create a new, empty + # session if the existing session corresponds to a different + # authenticated user. + request.session.flush() + else: + request.session.cycle_key() request.session[SESSION_KEY] = user.id request.session[BACKEND_SESSION_KEY] = user.backend if hasattr(request, 'user'): diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index b553fa4d58..b4cdeadd81 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -239,6 +239,16 @@ class SessionBase(object): self.delete() self.create() + def cycle_key(self): + """ + Creates a new session key, whilst retaining the current session data. + """ + data = self._session_cache + key = self.session_key + self.create() + self._session_cache = data + self.delete(key) + # Methods that child classes must implement. def exists(self, session_key): diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py index ffa32d6ae1..5efc17df00 100644 --- a/django/contrib/sessions/tests.py +++ b/django/contrib/sessions/tests.py @@ -37,6 +37,15 @@ False False >>> db_session.modified, db_session.accessed (True, True) +>>> db_session['a'], db_session['b'] = 'c', 'd' +>>> db_session.save() +>>> prev_key = db_session.session_key +>>> prev_data = db_session.items() +>>> db_session.cycle_key() +>>> db_session.session_key == prev_key +False +>>> db_session.items() == prev_data +True # Submitting an invalid session key (either by guessing, or if the db has # removed the key) results in a new key being generated. @@ -75,6 +84,16 @@ False False >>> file_session.modified, file_session.accessed (True, True) +>>> file_session['a'], file_session['b'] = 'c', 'd' +>>> file_session.save() +>>> prev_key = file_session.session_key +>>> prev_data = file_session.items() +>>> file_session.cycle_key() +>>> file_session.session_key == prev_key +False +>>> file_session.items() == prev_data +True + >>> Session.objects.filter(pk=file_session.session_key).delete() >>> file_session = FileSession(file_session.session_key) >>> file_session.save() @@ -112,6 +131,16 @@ False False >>> cache_session.modified, cache_session.accessed (True, True) +>>> cache_session['a'], cache_session['b'] = 'c', 'd' +>>> cache_session.save() +>>> prev_key = cache_session.session_key +>>> prev_data = cache_session.items() +>>> cache_session.cycle_key() +>>> cache_session.session_key == prev_key +False +>>> cache_session.items() == prev_data +True + >>> Session.objects.filter(pk=cache_session.session_key).delete() >>> cache_session = CacheSession(cache_session.session_key) >>> cache_session.save() |
