#36819: Async login does not reuse authenticated user instance
-------------------------------------+-------------------------------------
     Reporter:  Mykhailo Havelia     |                     Type:
                                     |  Cleanup/optimization
       Status:  new                  |                Component:
                                     |  contrib.auth
      Version:  6.0                  |                 Severity:  Normal
     Keywords:  async                |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
 **Problem**

 When using alogin, calling `request.auser` does not reuse the already
 authenticated user instance, resulting in redundant authentication
 requests.

 **Details**

 **Middleware Setup**

 {{{
 class AuthenticationMiddleware(MiddlewareMixin):
     def process_request(self, request):
         ...
         request.user = SimpleLazyObject(lambda: get_user(request))
         request.auser = partial(auser, request)
 }}}

 **Sync Login**

 {{{
 def login(request, user, backend=None):
     ...
     request.user = user
 }}}

 **Async Login**

 {{{
 def alogin(request, user, backend=None):
     ...
     request.user = user
 }}}

 **Problematic Behavior**

 After calling `alogin(request, user)`, `request.user` is set to the
 authenticated user instance. However, `request.auser()` does not use this
 instance and instead performs authentication again, relying on its own
 `_acached_user` cache.

 **Expected Behavior**

 After `alogin`, both `request.user` and `request.auser()` should reference
 the same user instance, avoiding duplicate authentication.

 **Suggested Solution**

 Set a shared cache. `request._cached_user = user`, in `alogin`, so both
 sync and async accessors use the same instance.

 {{{
 async def alogin(request, user, backend=None):
     ...
     request.user = user
     request._cached_user = user  # <-- suggested addition

 async def auser(request):
     if not hasattr(request, "_cached_user"):   # <-- suggested change
 (_acached_user -> _cached_user)
         request._cached_user = await auth.aget_user(request)
     return request._cached_user
 }}}

 See related discussion:
 https://github.com/django/django/pull/16552#discussion_r1122929933
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36819>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/0107019b4649c4a7-f128e8eb-69ff-4fc9-8947-4f25e2f3b1c1-000000%40eu-central-1.amazonses.com.

Reply via email to