Skip to content

Change Proposal on TokenAuthentication #7917

@quertenmont

Description

@quertenmont

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions