Почему бэкэнд аутентификации по умолчанию для django вызывает set_password после вызова исключения UserModel.DoesNotExist?

Я пишу пользовательский аутентификационный бэкэнд для пользовательской модели, унаследованной от AbstractUser в django. Я прошел по умолчанию аутентификационный бэкэнд django и увидел, что пользовательский объект выбирается с использованием имени пользователя с UserModel._default_manager.get_by_natural_key(username) authenticate() как ниже

def authenticate(self, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        try:
            user = UserModel._default_manager.get_by_natural_key(username)
            if user.check_password(password):
                return user
        except UserModel.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a non-existing user (#20760).
            UserModel().set_password(password)

Я уже написал свой собственный aut-backend, но из любопытства спрашиваю: зачем проверка пароля при исключении типа DidNotExist?

я пытался ipdb в методе authenticate и проверил, что при получении имени пользователя несуществующего пользователя поток управления переходит к блоку кроме. И UserModel().set_password(password) был выдан в терминале. Не зная, что происходит в фоновом режиме, я проверил код set_password() из auth.models, Но это было просто повышение NotImplementedError исключение. Я не уверен, как это помогает.

Также как raise a UserDoesNotExist or django.core.exceptions.ObjectDoesNotExist exception correctly после неудачной операции выборки объекта на пользовательской модели в пользовательском бэкэнде аутентификации? Идея состоит в том, чтобы остановить выполнение и предоставить пользователю правильное сообщение обратной связи вместо того, чтобы вызывать исключение и пробовать следующий аутентификационный бэкэнд, как указано в AUTHENTICATION_BACKENDS() в settings.py.

ТИА

2 ответа

Решение

Комментарий объясняет точно, почему. Если он немедленно вернул False, это заняло бы гораздо меньше времени, чем для несуществующего пользователя. Затем злоумышленник сможет определить разницу между существующим и несуществующим именем пользователя.

Вы должны прочитать это:

https://code.djangoproject.com/ticket/20760

Он должен убедиться, что если пользователь не выйдет из него, вернитесь не слишком скоро, чтобы бот мог знать, существует ли пользователь или нет.

Другие вопросы по тегам