#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.