Opened 7 weeks ago
Closed 6 weeks ago
#36540 closed Bug (fixed)
alogout does not clear the request.auser attribute
Reported by: | Xdynix | Owned by: | Xdynix |
---|---|---|---|
Component: | contrib.auth | Version: | 5.2 |
Severity: | Normal | Keywords: | |
Cc: | Jon Janzen | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
The request.auser method caches the user in _acached_user, which is not cleared during alogout. Therefore, the following view code will behave unexpectedly.
def delete_session(request: HttpRequest) -> None: logger.info("Current user:", user=request.user.username) # user="user" logout(request) logger.info("Current user:", user=request.user.username) # user="" return None async def delete_session(request: HttpRequest) -> None: logger.info("Current user:", user=(await request.auser()).username) # user="user" await alogout(request) logger.info("Current user:", user=(await request.auser()).username) # user="user" return None
It should be able to be fixed by adding the following to alogout.
if hasattr(request, "_acached_user"): delattr(request, "_acached_user")
Change History (9)
comment:1 by , 7 weeks ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:2 by , 7 weeks ago
The problematic code is within django/contrib/auth/middleware.py.
Add the following test case to auth_tests.test_middleware.TestAuthenticationMiddleware and you can reproduce it:
async def test_auser_logout(self): from django.contrib.auth import alogout from django.contrib.auth.models import AnonymousUser self.middleware(self.request) auser = await self.request.auser() self.assertEqual(auser, self.user) await alogout(self.request) auser_second = await self.request.auser() self.assertIsInstance(auser_second, AnonymousUser)
comment:3 by , 7 weeks ago
Resolution: | worksforme |
---|---|
Status: | closed → new |
comment:4 by , 7 weeks ago
Cc: | added |
---|---|
Summary: | `alogout` is not cleaning user cache correctly → alogout does not clear the request.auser attribute |
Triage Stage: | Unreviewed → Accepted |
Thank you for the clarification and the test
Apologies, it makes sense we are refering to auser
, rather than user
, in the async case.
Confirmed that this bug has been present since alogout
was implemented in 5e98959d9242c57a55c65847758781f82d386fa4 (5.0)
Here is a possible fix:
-
django/contrib/auth/__init__.py
a b async def alogout(request): 269 269 user = None 270 270 await user_logged_out.asend(sender=user.__class__, request=request, user=user) 271 271 await request.session.aflush() 272 if hasattr(request, " user"):272 if hasattr(request, "auser"): 273 273 from django.contrib.auth.models import AnonymousUser 274 async def auser(): 275 return AnonymousUser() 274 276 275 request. user = AnonymousUser()277 request.auser = auser 276 278 277 279 278 280 def get_user_model():
Would you like to prepare a PR? This would include your test
comment:5 by , 7 weeks ago
Has patch: | set |
---|---|
Owner: | set to |
Status: | new → assigned |
Sure, I will submit a PR for it.
comment:7 by , 7 weeks ago
Patch needs improvement: | set |
---|
comment:8 by , 6 weeks ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
I can't replicate. The behavior also matches the sync behavior
tests/async/test_async_auth.py