About User Sessions on Login

In the user_logged_in signal handler, the sessionid cookie still points to the anonymous user session, whereas request.session has the new authenticated user session which key will be saved as sessionid cookie when returning the response.

This information can be used to copy data from the anonymous session to the authenticated one:

from importlib import import_module
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
from django.conf import settings

@receiver(user_logged_in)
def on_user_logged_in(sender, request, user, **kwargs):
    # 1. sessionid cookie still points to anonymous user session
    engine = import_module(settings.SESSION_ENGINE)
    anonymous_user_session = engine.SessionStore(
        session_key=request.COOKIES.get("sessionid")
    )
    try:
        data = anonymous_user_session.load()
    except engine.SessionStore.DoesNotExist:
        # invalid or expired session key
        return

    # 2. request.session has a new authenticated user session
    authenticated_user_session = request.session

    # 3. copy data from one session to another
    PROTECTED_KEYS = {
        "_auth_user_id", "_auth_user_backend", "_auth_user_hash"
    }

    for key, value in data.items():
        if key not in PROTECTED_KEYS:
            authenticated_user_session.setdefault(key, value)

Tips and Tricks Programming Django 6.x Django 5.2 Django 4.2 Signals