dunmaksim
@dunmaksim
Технический писатель

Django authenticate() всегда возвращает None, а SO не даёт ответа на вопрос. Что делать?

Здравствуйте!

Сегодня обнаружил неприятную вещь - самописный модуль авторизации сломался. Если раньше работал вот этот код, то теперь - нет:

class LoginView(AuthView, GenericAPIView):

    """
    Вид предназначен для простой аутентификации
    """

    def post(self, request, *args, **kwargs):
        data = request.data

        username = data.get('username', None)
        email = data.get('email', None)
        password = data.get('password', None)

        if username is None:
            username = email

        account = authenticate(username=username, password=password)

        if account is None:
            raise Exception("Не удалось авторизоваться")

        if account is not None:
            if account.is_active:
                login(request, account)
                return Response(status=status.HTTP_200_OK)
            else:
                return Response({
                    'status': 'Unauthorized',
                    'message': 'This account has been disabled.'
                }, status=status.HTTP_401_UNAUTHORIZED)
        else:
            return Response({
                'status': 'Unauthorized',
                'message': 'Имя пользователя или пароль указаны неверно.'
            }, status=status.HTTP_401_UNAUTHORIZED)


Функция authenticate() всегда выдаёт None, даже при аутентификации в Django shell. Куда копать? В чём причина? CSRF-токены передаю, логины и пароли верные, задавал через set_password() и всё такое. Не могу авторизоваться, хотя ещё вчера всё работало.
В settings.py:

AUTH_USER_MODEL = 'extuser.User'

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.locale.LocaleMiddleware',
)
  • Вопрос задан
  • 1330 просмотров
Решения вопроса 2
crazyzubr
@crazyzubr
Python backend-developer
Для отладки вместо стандартной функции authenticate пропишите копию выше вьюхи, например:

def authenticate(username=None, password=None, **kwargs):
        from django.contrib.auth import get_user_model
        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)


После чего можно отследить в каком месте происходит затык. UserModel.DoesNotExist или не проходит user.check_password(password). Это также можно сделать через IDE в debug режиме, без копирования кода.

Можно предположить, что менялась модель юзера, а миграции проведены не были.
Ответ написан
Комментировать
un1t
@un1t
После set_password еще как минимум save надо сделать. Через админку поменяй парлоь, чтобы точно быть уверенным, что он верный.

Ну и вот этот кусок выглядит странно,
if username is None:
    username = email

авторизация же по username идет, а если ты тут email подставляешь

Такой код позволяет отправить пост запрос в котором нет указанных полей и ты об это не узнаешь.
username = data.get('username', None)
email = data.get('email', None)
password = data.get('password', None)

Хотя бы для теста ассерты вставь. Может верстальщик там намутил че, поля переименовал.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы