Reputation: 2197
I have a following question regarding Django authentication middleware:
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'session'), (
"The Django authentication middleware requires session middleware "
"to be installed. Edit your MIDDLEWARE setting to insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
)
request.user = SimpleLazyObject(lambda: get_user(request))
As you can see here middleware calls method get_user from backend (in my case simple_jwt) and puts this method in a SimpleLazyObject
in order to evaluate later.
def get_user(self, validated_token):
"""
Attempts to find and return a user using the given validated token.
"""
try:
user_id = validated_token[api_settings.USER_ID_CLAIM]
except KeyError:
raise InvalidToken(_('Token contained no recognizable user identification'))
try:
user = User.objects.get(**{api_settings.USER_ID_FIELD: user_id})
except User.DoesNotExist:
raise AuthenticationFailed(_('User not found'), code='user_not_found')
if not user.is_active:
raise AuthenticationFailed(_('User is inactive'), code='user_inactive')
return user
What I want to do is to keep request.user = SimpleLazyObject(lambda: get_user(request))
in order to provide user instance for apps that uses it but for my custom apps I want to add something like
request.user_id = user_id from user (user_id = validated_token[api_settings.USER_ID_CLAIM])
in order to not query database each and every request for user object in case I need only user_id
which I already have directly in get_user
method in backend.
Question – how to pass user_id
from get_user()
to AuthenticationMiddleware.process_request()
and set request.user_id
attribute to request without evaluating SimpleLazyObject
?
Strangelly i can't assign attributes to request in class JWTAuthentication(authentication.BaseAuthentication):
where get_user()
is belong
Thank you.
Internal Server Error: /auth/users/me/
Traceback (most recent call last):
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\asgiref\sync.py", line 330, in thread_handler
raise exc_info[1]
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\django\core\handlers\exception.py", line 38, in inner
response = await get_response(request)
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\django\utils\deprecation.py", line 126, in __acall__
response = await sync_to_async(
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\asgiref\sync.py", line 296, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "C:\ProgramData\Miniconda3\envs\entropy\lib\asyncio\tasks.py", line 440, in wait_for
return await fut
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\asgiref\current_thread_executor.py", line 23, in run
result = self.fn(*self.args, **self.kwargs)
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\asgiref\sync.py", line 334, in thread_handler
return func(*args, **kwargs)
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\django\contrib\auth\middleware.py", line 26, in process_request
request.user_id = _get_user_session_key(request)
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\django\contrib\auth\__init__.py", line 58, in _get_user_session_key
return get_user_model()._meta.pk.to_python(request.session[SESSION_KEY])
File "C:\ProgramData\Miniconda3\envs\entropy\lib\site-packages\django\contrib\sessions\backends\base.py", line 65, in __getitem__
return self._session[key]
KeyError: '_auth_user_id'
Upvotes: 1
Views: 809
Reputation:
You already have the user id available. It's decoded from the session inside auth.get_user() and you can just copy that to your own MiddleWare:
from django.contrib.auth import _get_user_session_key
request.user_id = _get_user_session_key(request)
This is a Django private API, not sure why they kept it private. But you can also just copy the one liner it implements:
request.user_id = get_user_model()._meta.pk.to_python(
request.session[SESSION_KEY]
)
Upvotes: 1