I propose a switch of logic regarding the TokenAuthentication class.
Today the authentication is done by getting the token with a select_related on the user.
This current approach is different from other authentication scheme, where the get is done on the user and credentical are checked in a second step.
The issue with the current approach is that you can't define "select_related" or other customization on the UserModel default manager. So I would propose to swap the logic to make the get on the user model itself and joined on the token table.
Today:
def authenticate_credentials(self, key):
model = self.get_model()
try:
token = model.objects.select_related('user').get(key=key)
except model.DoesNotExist:
raise exceptions.AuthenticationFailed(_('Invalid token.'))
if not token.user.is_active:
raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
return (token.user, token)
My Proposal:
from django.contrib.auth import get_user_model
from rest_framework.authentication import TokenAuthentication as DefaultTokenAuthentication
class TokenAuthentication(DefaultTokenAuthentication):
def authenticate_credentials(self, key):
try:
user = get_user_model()._default_manager.select_related("auth_token").get(auth_token__key=key)
except model.DoesNotExist:
raise exceptions.AuthenticationFailed(_('Invalid token.'))
if not user.is_active:
raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
return (user, user.auth_token)
That's quite a minor change but it allows to improve the performance on joined user tables (typically on the user profile table)
I propose a switch of logic regarding the TokenAuthentication class.
Today the authentication is done by getting the token with a select_related on the user.
This current approach is different from other authentication scheme, where the get is done on the user and credentical are checked in a second step.
The issue with the current approach is that you can't define "select_related" or other customization on the UserModel default manager. So I would propose to swap the logic to make the get on the user model itself and joined on the token table.
Today:
My Proposal:
That's quite a minor change but it allows to improve the performance on joined user tables (typically on the user profile table)