Commit c8c159cb authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

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
parent 2f7d6243
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -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.

    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'):
+10 −0
Original line number Diff line number Diff line
@@ -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):
+29 −0
Original line number Diff line number Diff line
@@ -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()