Django База [2023]: Авторизация по email и по логину (свой бекенд аутентификации) 👨💻 #41
В Django можно настроить авторизацию по email и по логину одновременно. Для этого можно использовать стандартную модель пользователя Django. Но учтите, я советую вам сделать поле email уникальным, наследуясь от модели AbstractUser. В рамках курса я использую стандартную модель Django с профилем через связь один-к-одному.
Если вы хотите выразить благодарность автору сайта, статей и курса по 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'
]