Hi all,
I have this weird problem: request.user is not returning the correct user
(in certain execution path). I think it is related to lazy evaluation of
request.user.
=========================================
I will summarize the business logic and the problem:
=========================================
All REST APIs are protected by Basic Authentication (username/password info
is persisted in Postgres)
// rest_framework/views.py
def perform_authentication(self, request):
request.user
In a nutshell, the above "request.user" is acting weird!
Normal path: perform_authentication() is called, and request.user will be
evaluated, and subsequently request._authenticate() is invoked.
Abnormal path: perform_authentication() is called, and request.user will be
evaluated, but somehow in request.__getattribute__(), "return
super(Request, self).__getattribute__(attr)" will magically returns an
incorrect user object without invoking request.user(). The returned user
object is pointing to a different user. This user seems be from a different
REST API invocation prior with return status 500.
It seems somehow a failed REST API call is effecting other REST API
invocations, and the problem will continue until I restart Django. If there
is no failed call, there seems to be no problem.
It is difficult to debug this problem with debugger because it is easy to
accidentally force the evaluation of the request.user, and the problem will
go away.
I have a workaround in perform_authentication(); there I can add some code
to force explicit call to request._authenticate() prior to "request.user".
I wonder if others have seen similar problems?
Is this a known bug? Or I did something wrong?
Is there existing solutions?
Any tips is appreciated.
Thanks in advance.
Steve
==============================
Related sources
==============================
// rest_framework/views.py
def perform_authentication(self, request):
"""
Perform authentication on the incoming request.
Note that if you override this and simply 'pass', then
authentication
will instead be performed lazily, the first time either
`request.user` or `request.auth` is accessed.
"""
request.user
// rest_framework/request.py
@property
def user(self):
print("***sleung get user***")
"""
Returns the user associated with the current request, as
authenticated
by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'):
self._authenticate()
return self._user
// rest_framework/request.py
def __getattribute__(self, attr):
"""
If an attribute does not exist on this instance, then we also
attempt
to proxy it to the underlying HttpRequest object.
"""
try:
return super(Request, self).__getattribute__(attr)
except AttributeError:
info = sys.exc_info()
try:
return getattr(self._request, attr)
except AttributeError:
six.reraise(info[0], info[1], info[2].tb_next)
============================
Below are my configuration details:
============================
Ubuntu 16.04 LTS
Python 3.5.2
Django (1.9.12)
djangorestframework (3.3.3)
--
You received this message because you are subscribed to the Google Groups
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.