[Django] #37042: alogin() does not invalidate _acached_user, causing stale AnonymousUser after async login

2 views
Skip to first unread message

Django

unread,
Apr 17, 2026, 6:41:44 AM (yesterday) Apr 17
to django-...@googlegroups.com
#37042: alogin() does not invalidate _acached_user, causing stale AnonymousUser
after async login
-------------------------------------+-------------------------------------
Reporter: Dong Huynh | Type: Bug
Status: new | Component:
| contrib.auth
Version: 5.2 | Severity: Normal
Keywords: alogin, async, | Triage Stage:
auser | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
When alogin() is called after request.auser() in the same request,
subsequent calls to request.auser() return a stale AnonymousUser because
alogin() does not update request._acached_user.

The sync path does not have this problem. login() sets request.user =
user, which replaces the SimpleLazyObject entirely, so all subsequent
request.user access returns the correct user. But in the async path,
request.auser() is a separate callable (partial(auser, request)) that
caches its result in request._acached_user. alogin() updates request.user
but never touches _acached_user.

Reproduction:

{{{
class MyAuthMiddleware:
async def __acall__(self, request):
# Step 1: check if already authenticated
user = await request.auser() # caches AnonymousUser in
_acached_user

if not user.is_authenticated:
db_user = await
User.objects.aget(email="exis...@example.com")
await alogin(request, db_user) # updates request.user, NOT
_acached_user

response = await self.get_response(request) # view runs
return response

# In the view:
async def my_view(request):
user = await request.auser() # returns stale AnonymousUser
assert user.is_authenticated # FAILS
}}}

Fixed in: Django 6.x, which replaces request.auser with a closure after
login:

{{{
if hasattr(request, "auser"):
async def auser():
return user
request.auser = auser
}}}

Workaround for 5.x, after await alogin(request, user):

{{{
request._acached_user = user # Fixed in Django 6.x (alogin replaces
request.auser)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/37042>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 17, 2026, 7:17:56 AM (yesterday) Apr 17
to django-...@googlegroups.com
#37042: alogin() does not invalidate _acached_user, causing stale AnonymousUser
after async login
-------------------------------------+-------------------------------------
Reporter: Dong Huynh | Owner: (none)
Type: Bug | Status: closed
Component: contrib.auth | Version: 5.2
Severity: Normal | Resolution: duplicate
Keywords: alogin, async, | Triage Stage:
auser | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* resolution: => duplicate
* status: new => closed

Comment:

Duplicate of #36540 which (as you said) is now fixed from 6.0
--
Ticket URL: <https://code.djangoproject.com/ticket/37042#comment:1>
Reply all
Reply to author
Forward
0 new messages