Аутентификация по email

За то, как будет обработана форма авторизации на нашем сайте в Django отвечает настройка AUTHENTICATION_BACKENDS. Если, конечно, вы не написали свой механизм взаимодействия с пользователями.

AUTHENTICATION_BACKENDS представляет из себя список, содержащий перечисление бэкендов-обработчиков "входа". Да, их может быть несколько. Хотя сработает только один - первый, результат работы которого будет успешен. Соответственно, если ни один не сможет идентифицировать(аутентифицировать, если использовать правильную терминологию) авторизирующегося пользователя, то будет отображено сообщение об ошибке. С предложением повторной попытки, но с другими пользовательскими данными.

По-умолчанию указан всего один базовый бэкенд - ModelBackend из django.contrib.auth.backends. Тот, что ожидает ввода имени и пароля соответствующих хранящимся в БД значениям для одной из моделей User. Если наши потребности такой вариант не покрывает, то ничто не мешает создать собственный сценарий обработки.

Создание своего обработчика формы авторизации

В качестве примера кастомного бэкенда мы рассмотрим написание такового для возможности авторизации пользователя по его email-адресу, указанному в профиле. И паролю, само собой.

Класс, который опишет нужный нам бэкенд, мы поместим в отдельный файл в директорию некоего приложения.

# some_app/auth_backends.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import check_password
    
class UserEmailBackend(ModelBackend):
    '''
    Класс-обработчик для аутентификации пользователей по 
    email-адресу.
    '''
    def authenticate(self, username="", password="", **kwargs):
        '''
        Переопределяем метод аутентификации.
        '''
        user_model = get_user_model()
        try:
            # Ищем совпадение по email у пользовательских моделей в БД.
            # Если находим - сверяем пароли.
            user = user_model.objects.get(email__iexact=username)
            if check_password(password, user.password):
                return user
            else:
                return None
        # В случае "неуспеха" проверки ловим соответствующее
        # исключение и возвращаем отрицательный результат.
        except user_model.DoesNotExist:
            return None

Вот и весь код. Просто и незамысловато. Теперь, что бы воспользоваться новым функционалом оповестим о нем фреймворк, добавив в settings.py соответствующие данные.

# settings.py
AUTHENTICATION_BACKENDS = [
 'some_app.auth_backends.UserEmailBackend',
]

Если возможность авторизации по имени тоже нужна, то задаем оба бэкенда.

# settings.py
AUTHENTICATION_BACKENDS = [
 'some_app.auth_backends.UserEmailBackend',
 'django.contrib.auth.backends.ModelBackend', 
]
dalay
Арсений сказал(а):
оправьте 'some_app.auth_backends.EmailBackend', на 'some_app.auth_backends.UserEmailBackend', так …

Поправил. Спасибо.

Арсений | 95.67.140.95
Mar сказал(а):
Просто то как.

оправьте 'some_app.auth_backends.EmailBackend', на 'some_app.auth_backends.UserEmailBackend',
так же данные настройки у меня заработали только после restarts nginx.
А так в общем , ваше решение самое адекватное для реализации данной задачи.

Mar | 109.172.58.22

Просто то как.