summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2026-04-01 09:36:16 -0400
committerJacob Walls <jacobtylerwalls@gmail.com>2026-04-02 09:01:19 -0400
commita5c28dc1d7606f11adb932d0bd4dba899a028007 (patch)
tree50cdbb8e8c4b0d1eb4f630560216f5ecdc38c6a4
parent3436edb6966a83ac6be06dbc422df89fdc9e5653 (diff)
[6.0.x] Fixed #37017 -- Fixed setting or clearing of request.user after alogin/alogout().
Regression in 31a43c571f4d036827d4fd7a5f615591637dc1be. Backport of a32c7075cf634aee1f4f3deecd27f194097ec0c2 from main.
-rw-r--r--django/contrib/auth/__init__.py18
-rw-r--r--docs/releases/6.0.4.txt5
-rw-r--r--tests/auth_tests/test_middleware.py31
3 files changed, 48 insertions, 6 deletions
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index 1119ef4f91..db08bdff13 100644
--- a/django/contrib/auth/__init__.py
+++ b/django/contrib/auth/__init__.py
@@ -234,6 +234,8 @@ async def alogin(request, user, backend=None):
await request.session.aset(SESSION_KEY, user._meta.pk.value_to_string(user))
await request.session.aset(BACKEND_SESSION_KEY, backend)
await request.session.aset(HASH_SESSION_KEY, session_auth_hash)
+ if hasattr(request, "user"):
+ request.user = user
if hasattr(request, "auser"):
async def auser():
@@ -273,13 +275,21 @@ async def alogout(request):
user = None
await user_logged_out.asend(sender=user.__class__, request=request, user=user)
await request.session.aflush()
- if hasattr(request, "auser"):
+
+ has_user = hasattr(request, "user")
+ has_auser = hasattr(request, "auser")
+ if has_user or has_auser:
from django.contrib.auth.models import AnonymousUser
- async def auser():
- return AnonymousUser()
+ anon = AnonymousUser()
+ if has_user:
+ request.user = anon
+ if has_auser:
- request.auser = auser
+ async def auser():
+ return anon
+
+ request.auser = auser
def get_user_model():
diff --git a/docs/releases/6.0.4.txt b/docs/releases/6.0.4.txt
index a32a49dc93..e24397d9bc 100644
--- a/docs/releases/6.0.4.txt
+++ b/docs/releases/6.0.4.txt
@@ -10,4 +10,7 @@ issues with severity "low", and several bugs in 6.0.3.
Bugfixes
========
-* ...
+* Fixed a regression in Django 6.0 where :func:`~django.contrib.auth.alogin`
+ and :func:`~django.contrib.auth.alogout` did not respectively set or clear
+ ``request.user`` if it had already been materialized (e.g., by sync
+ middleware) (:ticket:`37017`).
diff --git a/tests/auth_tests/test_middleware.py b/tests/auth_tests/test_middleware.py
index 5e106d40f7..894b49548b 100644
--- a/tests/auth_tests/test_middleware.py
+++ b/tests/auth_tests/test_middleware.py
@@ -4,7 +4,7 @@ from django.contrib.auth.middleware import (
AuthenticationMiddleware,
LoginRequiredMiddleware,
)
-from django.contrib.auth.models import User
+from django.contrib.auth.models import AnonymousUser, User
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpRequest, HttpResponse
from django.test import TestCase, modify_settings, override_settings
@@ -77,6 +77,35 @@ class TestAuthenticationMiddleware(TestCase):
self.assertTrue(auser_second.is_anonymous)
+class TestAsyncLoginLogoutAfterSyncMiddleware(TestCase):
+ @classmethod
+ def setUpTestData(cls):
+ cls.user = User.objects.create_user(
+ "test_user", "test@example.com", "test_password"
+ )
+ cls.user2 = User.objects.create_user(
+ "test_user2", "test2@example.com", "test_password2"
+ )
+
+ def setUp(self):
+ self.middleware = AuthenticationMiddleware(lambda req: HttpResponse())
+ self.client.force_login(self.user)
+ self.request = HttpRequest()
+ self.request.session = self.client.session
+ # Populate self.request.user.
+ self.middleware(self.request)
+ # .user is lazy, so materialize it by accessing an attribute.
+ self.request.user.is_authenticated
+
+ async def test_user_after_alogin(self):
+ await alogin(self.request, self.user2)
+ self.assertEqual(self.request.user, self.user2)
+
+ async def test_user_after_alogout(self):
+ await alogout(self.request)
+ self.assertEqual(self.request.user, AnonymousUser())
+
+
@override_settings(ROOT_URLCONF="auth_tests.urls")
@modify_settings(
MIDDLEWARE={"append": "django.contrib.auth.middleware.LoginRequiredMiddleware"}