Аутентификация Django для использования электронной почты и имени пользователя

Я почти закончил свое приложение django-react со всеми моделями, сериализаторами и API. Но теперь мне нужно изменить метод аутентификации, чтобы он также использовал email.

class User(AbstractUser):
   id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
   email = models.EmailField(unique=True)

   # Notice there is no username field, because it is included in AbstractUser

Я просмотрел несколько возможных решений, но они предполагают использование AbstractBaseUser, в то время как некоторые другие пишут собственный бэкенд аутентификации, который полностью опускает username. Это может сломать другие представления и фронтенд, так как мы в основном используем username.

Я все еще хочу сохранить имя пользователя и использовать оба имя пользователя и email для аутентификации.

Есть ли какая-нибудь простая идея (желательно с использованием AbstractUser), которую мне не пришлось бы сильно менять?

Этот код взят из книги "Django 3 на примере", глава 4, раздел "Building a custom authentication backend".

Django предоставляет простой способ определения собственных бэкендов аутентификации. Бэкенд аутентификации - это класс, который предоставляет следующие два метода: authenticate() и get_user().

Предположим, что в вашем проекте есть приложение account для управления логикой аутентификации. Вы можете создать файл authentication.py со следующим кодом:

class EmailAuthBackend(object):
    """
    Authenticate using an e-mail address.
    """
    def authenticate(self, request, username=None, password=None):
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
            return None
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Предшествующий код работает следующим образом:

  • authenticate(): Вы пытаетесь получить пользователя с заданным адресом электронной почты и проверить пароль, используя встроенный метод check_password() модели пользователя. Этот метод обрабатывает хэширование пароля для сравнения заданного пароля с паролем, хранящимся в базе данных.
  • get_user(): Вы получаете пользователя через ID, предоставленный в параметре user_id. Django использует бэкенд, который аутентифицировал пользователя, для получения объекта User на время сессии пользователя.

Отредактируйте settings.py файл вашего проекта и добавьте следующую настройку:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'account.authentication.EmailAuthBackend',
]

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

Django попытается аутентифицировать пользователя по каждому из бэкендов, так что теперь вы должны иметь возможность беспрепятственно войти в систему, используя свое имя пользователя или учетную запись электронной почты. Учетные данные пользователя будут проверены с помощью бэкенда аутентификации ModelBackend, а если пользователь не найден, то учетные данные будут проверены с помощью вашего пользовательского бэкенда EmailAuthBackend.

Вернуться на верх