Using login() loses the session data

authentication, django, session

Solution

login source:

def login(request, user):
    """
    Persist a user id and a backend in the request. This way a user doesn't
    have to reauthenticate on every request. Note that data set during
    the anonymous session is retained when the user logs in.
    """
    if user is None:
        user = request.user
    # TODO: It would be nice to support different login methods, like signed cookies.
    if SESSION_KEY in request.session:
        if request.session[SESSION_KEY] != user.pk:
            # 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.pk
    request.session[BACKEND_SESSION_KEY] = user.backend
    if hasattr(request, 'user'):
        request.user = user
    user_logged_in.send(sender=user.__class__, request=request, user=user)

Anonymous sessions are retained (they don't have a `SESSION_KEY`), relogin as a different user flushes session.

Logout also flushes the session:

def logout(request):
    """
    Removes the authenticated user's ID from the request and flushes their
    session data.
    """
    # Dispatch the signal before the user is logged out so the receivers have a
    # chance to find out *who* logged out.
    user = getattr(request, 'user', None)
    if hasattr(user, 'is_authenticated') and not user.is_authenticated():
        user = None
    user_logged_out.send(sender=user.__class__, request=request, user=user)

    request.session.flush()
    if hasattr(request, 'user'):
        from django.contrib.auth.models import AnonymousUser
        request.user = AnonymousUser()

These are the only two cases when session is flushed.

You should set `current_day` after logging in (or check its existence on every request with a custom middleware).

Problem

When do sessions get created and destroyed? In my application I have ``` def app_login(request): request.session.set_expiry(0) if 'current_day' not in request.session: request.session['current_day'] = Utilities.default_day() ``` Then further down I use : ``` login(request, user) ``` If I login in as a user, this works fine and 'current_day' is retained in session. But if I log out as that user and log in as another, then 'current_day' is lost and is not available immediately after calling login(). I assume that ``` logout(request) ``` does not clear the session, and when the second user tries to login the data 'current_'day' is still available in the session but calling login(user) presumably creates a new session. Is this assumption correct and how best to correct this?

Original source