![Django База [2023]: Авторизация по email и по логину (свой бекенд аутентификации) 👨💻 #41](/_next/image?url=https%3A%2F%2Fproghunter.ru%2Fmedia%2Fimages%2Fthumbnails%2F2023%2F03%2F01%2Fimage-8f24fc9e25.png&w=3840&q=90)
Django База [2023]: Авторизация по email и по логину (свой бекенд аутентификации) 👨💻 #41
В Django можно настроить авторизацию по email и по логину одновременно. Для этого можно использовать стандартную модель пользователя Django. Но учтите, я советую вам сделать поле email уникальным, наследуясь от модели AbstractUser. В рамках курса я использую стандартную модель Django с профилем через связь один-к-одному.
Я обращаюсь к вам с просьбой о финансовой поддержке, чтобы помочь мне справиться с непредвиденной ситуацией, связанной с поломкой моей видеокарты. Как вы знаете, создание статей требует надежного оборудования, и видеокарта является важным компонентом для создания высококачественных материалов.
Я с большим энтузиазмом и преданностью занимаюсь написанием статей и созданием контента, который доступен абсолютно бесплатно. Моей целью является поделиться знаниями и помочь другим, но поломка видеокарты создала трудности и затраты, которые я самостоятельно не могу покрыть.
Ваше пожертвование поможет мне восстановиться от этой ситуации и продолжить создание качественного контента без препятствий. С каждым вкладом вы будете играть важную роль в моей возможности предоставлять информацию, обучение и вдохновение моим читателям и зрителям.
Все откликнувшиеся на зов помощи будут упомянуты после выполнения целей 🙏🏻
Виды расширений пользовательской модели
Переопределение системы аутентификации Django
Давайте создадим файл backends.py в приложении system со следующим фрагментом кода:
from django.contrib.auth.backends import ModelBackend, get_user_model
from django.core.exceptions import MultipleObjectsReturned
from django.db.models import Q
UserModel = get_user_model()
class UserModelBackend(ModelBackend):
"""
Переопределение авторизации
"""
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = UserModel.objects.get(Q(username=username) | Q(email__iexact=username))
except UserModel.DoesNotExist:
return None
except MultipleObjectsReturned:
return UserModel.objects.filter(email=username).order_by('id').first()
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
def get_user(self, user_id):
try:
user = UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None
Этот код определяет специальный бэкэнд аутентификации UserModelBackend, который расширяет стандартный ModelBackend Django. Бэкэнд позволяет пользователю авторизоваться по username или по email.
Для начала он импортирует ModelBackend и функцию get_user_model()
из Django. Затем он использует get_user_model()
, чтобы получить модель пользователя, связанную с текущей конфигурацией Django.
Затем определены два метода: authenticate()
и get_user()
.
Метод authenticate()
вызывается при попытке аутентификации пользователя. Он ищет пользователя в базе данных, используя UserModel.objects.get()
, и проверяет, соответствует ли введенный пароль тому, что хранится в базе данных. Если все верно, то пользователь возвращается.
Если пользователь не найден, то возвращается значение None. Если было найдено несколько пользователей, связанных с указанными username или email, то берется только первый, который найден.
Метод get_user()
вызывается при обращении к объекту пользователя request.user
. Если пользователь уже прошел аутентификацию, то Django запоминает его в request.user
. Этот метод проверяет, что пользователь валидный, и возвращает объект User или None, в зависимости от результата проверки.
Таким образом, код предоставляет более гибкий механизм аутентификации для приложения Django.
Добавление новых изменений в конфигурационный файл
Далее нам необходимо добавить наш улучшенный бекенд в settings.py, для этого добавим в любое место конфигурации:
AUTHENTICATION_BACKENDS = [
'modules.system.backends.UserModelBackend'
]
Проверка работы нового бекенда



