Особенности Django: пользовательские модели и аутентификация (часть 1)
Опубликовано: 2022-03-10Существует два типа веб-сайтов: статические и динамические. Django — это фреймворк для разработки динамических веб-сайтов. Хотя статический веб-сайт представляет собой исключительно информацию, никакое взаимодействие (кроме простых запросов страниц) не регистрируется на сервере. На статическом веб-сайте сервер отправляет клиенту HTML, CSS и JavaScript, и все. Дополнительные возможности требуют динамического веб-сайта, где сервер хранит информацию и реагирует на взаимодействие с пользователем, а не только на обслуживание страниц. Одной из основных причин разработки динамического сайта является аутентификация пользователей и ограничение контента.
Написание, развертывание и администрирование статического веб-сайта примерно на порядок проще, дешевле и безопаснее, чем динамический сайт. Таким образом, вам следует создавать динамический веб-сайт только в том случае, если для вашего проекта необходимы дополнительные возможности динамической парадигмы. Django упрощает и оптимизирует процесс создания динамического сайта с помощью встроенных компонентов. Как один из основных компонентов динамического веб-приложения, объект «учетная запись пользователя», как и колесо, заманчиво изобретать заново, но стандартная форма подходит для большинства применений. Django предоставляет мощную готовую пользовательскую модель, и в этой статье мы рассмотрим лучший способ обеспечения безопасных и интуитивно понятных процессов аутентификации пользователей.
Дальнейшие части в серии:
- Django Highlights: создание шаблонов строк сохранения (часть 2)
- Особенности Django: модели, администрирование и использование реляционной базы данных (часть 3)
- Основные моменты Django: работа со статическими активами и медиафайлами (часть 4)
Подготовка
Если вы хотите создать собственное приложение Django, чтобы поэкспериментировать с концепциями, изложенными в этой статье, вы можете создать каталог (и, желательно, виртуальную среду), а затем выполнить следующие команды:
pip install django django-admin startproject PROJECTNAME cd PROJECTNAME python manage.py startapp APPNAME python manage.py migrate python manage.py runserver
Если вы ищете пошаговое руководство по созданию вашего первого проекта Django, собственный веб-сайт Django предоставляет отличный вариант. В этой статье мы не используем пример проекта, но обсуждаемые концепции применимы практически к каждому приложению Django.
Стандартная пользовательская модель
По сути, концепция учетной записи пользователя существует по двум причинам: контроль доступа и персонализированное состояние приложения. Контроль доступа — это идея о том, что ресурсы в системе доступны только некоторым пользователям. Персонализированное состояние сильно зависит от цели приложения, но может включать настройки, данные или любые другие записи, характерные для отдельного пользователя. Стандартная User
модель Django предлагает разумные подходы к обоим вариантам использования.
Изначально в приложении Django есть два типа пользователей: учетные записи суперпользователя и обычные пользователи. Суперпользователи имеют все атрибуты и привилегии обычных учетных записей, но также имеют доступ к панели администратора Django, мощному приложению, которое мы подробно рассмотрим в следующей статье. По сути, суперпользователи могут создавать, редактировать или удалять любые данные в приложении, включая учетные записи других пользователей.
По сути, концепция учетной записи пользователя существует по двум причинам: контроль доступа и персонализированное состояние приложения.
“
Чтобы создать суперпользователя в собственном приложении Django, запустите:
python manage.py createsuperuser
Еще одним преимуществом учетной записи пользователя является сохранение персонализированных данных в базе данных. По умолчанию Django требует только имя пользователя и пароль, но предоставляет пользователям дополнительные поля для ввода своего имени, фамилии и адреса электронной почты. Вы можете прочитать полное описание модели на веб-сайте Django. Ниже мы обсудим расширение этой модели.
Безопасность и надежность
Django включает в себя существенное промежуточное ПО для управления паролями с пользовательской моделью. Пароли пользователей должны состоять не менее чем из 8 символов, а не полностью цифр, не слишком точно совпадать с именем пользователя и не входить в список из 20 000 наиболее распространенных паролей. Стандартные формы Django подтверждают эти требования. Когда пароль отправляется на сервер, он шифруется перед сохранением, по умолчанию с использованием алгоритма PBKDF2 с хэшем SHA256. В целом, система паролей по умолчанию обеспечивает надежную защиту без каких-либо усилий со стороны разработчика. Если у вас нет специального опыта и веских причин для изменения способа обработки паролей в вашем приложении, не изменяйте это поведение.
Еще одна удобная встроенная функция — требование уникальности имен пользователей. Если подумать, если бы было два пользователя с именем пользователя «djangofan1» и сервер получил запрос на вход для этого имени пользователя, он бы не знал, какой пользователь пытается получить доступ к приложению. К несчастью для них, второй пользователь, который попытается зарегистрироваться на «djangofan1», должен будет выбрать другое имя, возможно, «djangofan2». Это ограничение уникальности применяется на уровне базы данных, но снова проверяется формами, которые предоставляет Django.
Наконец, примечание об удалении пользователей. Хотя удаление пользователей возможно, большинство сложных приложений будут иметь ряд ресурсов, привязанных к каждой учетной записи пользователя. Если вы хотите эффективно удалить пользователя, не удаляя приложенные объекты, вместо этого установите для поля пользователя is_active
значение false. Затем эти другие ресурсы остаются связанными с учетной записью, а не удаляются сами по себе, и учетная запись пользователя может быть повторно активирована в любое время суперпользователем. Обратите внимание, что это не освобождает имя пользователя, но установка учетной записи как неактивной в сочетании с изменением имени пользователя на случайное уникальное значение может привести к тому же эффекту. Наконец, если правила вашего сайта или применимое местное законодательство требуют, чтобы учетные записи пользователей были полностью удаляемыми, подхода is_active
будет недостаточно.
Если у вас нет специального опыта и веских причин для изменения способа обработки паролей в вашем приложении, не изменяйте это поведение.
“
Стандартное использование
Когда вы хотите зарегистрировать новую учетную запись пользователя, представление для этого, вероятно, будет выглядеть примерно так в views.py :
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.forms import UserCreationForm def signup(request): if request.user.is_authenticated: return redirect('/') if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') password = form.cleaned_data.get('password1') user = authenticate(username=username, password=password) login(request, user) return redirect('/') else: return render(request, 'signup.html', {'form': form}) else: form = UserCreationForm() return render(request, 'signup.html', {'form': form})
Давайте разберем это:
- Если пользователь уже вошел в систему, мы перенаправим его со страницы регистрации.
- Если метод запроса POST, значит, форма для создания пользователя уже заполнена и пришло время создать пользователя.
- Сначала создайте объект формы на серверной части с предоставленными пользователем данными.
- Если форма действительна, создайте пользователя и войдите в него, а затем отправьте его на главную страницу.
- В противном случае сбросьте их обратно на страницу создания пользователя с информацией о том, какие данные были недействительны (например, они запросили уже используемое имя пользователя).
- В противном случае пользователь заходит на страницу в первый раз и должен увидеть форму для создания новой учетной записи.
Теперь изучаем вход в учетную запись:
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.forms import AuthenticationForm def signin(request): if request.user.is_authenticated: return render(request, 'homepage.html') if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('/') else: form = AuthenticationForm(request.POST) return render(request, 'signin.html', {'form': form}) else: form = AuthenticationForm() return render(request, 'signin.html', {'form': form})
Еще одна разбивка:
- Если пользователь уже вошел в систему, мы перенаправим его со страницы входа.
- Если метод запроса POST, это означает, что форма для входа заполнена и пришло время аутентифицировать пользователя в учетной записи.
- Сначала аутентифицируйте пользователя с помощью предоставленных пользователем данных.
- Если имя пользователя и пароль соответствуют учетной записи, войдите в систему
- В противном случае верните их на страницу входа с предварительно заполненной информацией формы.
- В противном случае пользователь заходит на страницу впервые и должен встретиться с формой для входа.
Наконец, ваши пользователи могут в конечном итоге захотеть выйти из системы. Базовый код для этого запроса прост:
from django.shortcuts import render, redirect from django.contrib.auth import logout def signout(request): logout(request) return redirect('/')
Как только пользователь вошел в свою учетную запись и пока он не вышел из системы на этом устройстве, у него есть «сеанс». В течение этого времени последующие запросы из их браузера смогут получить доступ только к страницам учетной записи. Пользователь может иметь несколько активных сеансов одновременно. По умолчанию время сеанса не истекает.
Пока пользователь имеет активный сеанс на своем устройстве, он будет зарегистрирован как True
для проверки request.user.is_authenticated
. Еще один способ ограничить страницы только зарегистрированными пользователями — это декоратор @login_required
над функцией. Есть несколько других способов добиться того же, подробно описанных здесь.
Если этот уровень конфигурации больше, чем вы хотите выполнить, существует еще более нестандартный подход к управлению пользователями. Эти стандартные представления аутентификации предоставляют стандартные маршруты, представления и формы для управления пользователями и могут быть изменены путем назначения им настраиваемых URL-адресов, передачи настраиваемых шаблонов или даже создания подклассов представлений для большего контроля.
Расширение пользовательской модели
Как правило, вам необходимо расширить пользовательскую модель, чтобы предоставить более детализированные элементы управления доступом или хранить больше пользовательских данных для каждой учетной записи. Ниже мы рассмотрим несколько распространенных случаев.
Удаление полей из пользовательской модели
Вопреки заголовку этого раздела, я на самом деле не рекомендую вносить изменения непосредственно в пользовательскую модель или связанную с ней схему базы данных! Общая пользовательская модель устанавливается в вашей базе данных по умолчанию во время настройки нового проекта Django. С пользовательской моделью по умолчанию так много связано, что ее изменение может иметь неожиданные последствия в вашем приложении (особенно если вы используете сторонние библиотеки), поэтому добавление или удаление полей не рекомендуется и не упрощается фреймворком.
По умолчанию для пользователя требуются только два поля: имя пользователя и пароль. Если вы не хотите использовать какие-либо другие поля, просто игнорируйте их существование, поскольку пользователь может быть создан без имени, фамилии или адреса электронной почты. Существует набор полей по умолчанию, таких как last_login и date_joined, которые также можно игнорировать, если они вам не нужны. Если бы у вас было реальное техническое ограничение, требующее удаления необязательных полей из пользовательской модели, вы бы уже знали об этом и не нуждались бы в этой статье.
Распространенной причиной, по которой вы можете захотеть удалить поле в модели пользователя, является отказ от имени пользователя в пользу электронной почты в качестве уникального идентификатора. В этом случае при создании пользователя из данных формы или аутентификации запроса просто введите адрес электронной почты в качестве имени пользователя в дополнение к его использованию в поле электронной почты. Поле имени пользователя по-прежнему будет применять ограничение уникальности, когда имена пользователей отформатированы как адреса электронной почты. Строки есть строки, они будут обрабатываться одинаково.
С пользовательской моделью по умолчанию так много связано, что ее изменение может привести к неожиданным последствиям в вашем приложении, особенно если вы используете сторонние библиотеки.
“
Добавление полей с профилем
Точно так же, если вы хотите сохранить дополнительную информацию о своих пользователях, вам не следует пытаться изменить пользовательскую модель по умолчанию. Даже для одного поля определите собственный объект с отношением один к одному с существующими пользователями. Эту дополнительную модель часто называют Profile
. Допустим, вы хотите сохранить отчество и дату рождения (dob) для каждого пользователя. Profile
будет определен в models.py следующим образом:
from django.db import models from django.contrib.auth.models import User class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) middle_name = models.CharField(max_length=30, blank=True) dob = models.DateField(null=True, blank=True)
Пользовательский контроль доступа
Вашему приложению может потребоваться различие между разными типами пользователей для доступа к информации и функциям. Django предоставляет систему для создания настраиваемого детального контроля доступа: разрешений и групп.
Разрешения — это объекты, определяющие доступ к ресурсам. Пользователь может иметь одно или несколько разрешений. Например, у них может быть доступ для чтения к таблице продуктов и доступ для записи к таблице клиентов. Точная реализация разрешений существенно различается в зависимости от приложения, но подход Django позволяет интуитивно определять разрешения для данных и назначать эти разрешения пользователям.
Приложения для предприятий и других крупных организаций часто реализуют управление доступом на основе ролей. По сути, пользователь может иметь различные роли, каждая из которых имеет определенные разрешения. Инструментом Django для реализации этого шаблона является Group. Группа может иметь любое количество разрешений, каждое из которых может быть назначено любому количеству групп. Затем пользователь получает разрешения не напрямую, а через свое членство в группах, что упрощает администрирование приложения.
Обзор: интеграция платежной системы
Точный процесс интеграции платежного процессора существенно зависит от приложения и поставщика. Тем не менее, я расскажу о процессе в общих чертах.
Одним из ключевых преимуществ аутсорсинговых платежей является то, что провайдер несет ответственность за хранение и проверку строго регулируемых данных, таких как информация о кредитной карте. Затем служба передает вашему приложению какой-то уникальный токен пользователя вместе с данными об их истории платежей. Как и при добавлении профиля, вы можете создать модель, связанную с основным User
, и сохранить данные в этой модели. Как и в случае с паролями, важно следовать заданной интеграции с провайдером, чтобы избежать неправильного хранения конфиденциальной информации.
Обзор: вход через социальные сети
Другая широкая и сложная область, которую я хочу кратко затронуть, — это вход через социальные сети. Крупные платформы, такие как Facebook и Google, а также небольшие сайты, такие как GitHub, предоставляют API для использования своих служб для аутентификации пользователей. Подобно платежному провайдеру, это создает запись в вашей базе данных, связывающую учетную запись с учетной записью в их базе данных.
Возможно, вы захотите включить социальную аутентификацию на свой сайт, чтобы пользователям было проще регистрироваться без создания нового набора учетных данных для входа. Если ваше приложение предназначено исключительно для клиентов, которые уже используют определенный сайт, предоставляющий опцию социальной аутентификации, это может помочь вам привлечь пользователей с этого рынка, снизив входной барьер. Кроме того, если ваше приложение намеревается получить доступ к данным пользователя из сторонней службы, связывание учетных записей во время аутентификации упрощает процесс предоставления разрешений.
Однако у использования социальной аутентификации есть и недостатки. Изменения или перебои в работе API от стороннего поставщика могут прервать время безотказной работы вашего приложения или действия по разработке. Как правило, внешние зависимости усложняют приложение. Наконец, стоит рассмотреть политики сбора и использования данных третьих сторон, с которыми вы интегрируетесь, и убедиться, что они соответствуют вашим ожиданиям и ожиданиям ваших пользователей.
Если вы решите, что социальная аутентификация подходит для вашего приложения, к счастью, для этого есть библиотека. Python Social Auth для Django — это пакет, позволяющий использовать возможности экосистемы социальной аутентификации Python в проектах Django.
Подведение итогов
Какой бы универсальной ни была учетная запись пользователя, ее широкое использование может привести к ненужному решению одних и тех же проблем. Надеюсь, эта статья показала вам ряд мощных функций, доступных в Django, и дала вам представление об основных обязанностях приложения при создании учетных записей пользователей.
Django Highlights — это серия, знакомящая с важными концепциями веб-разработки в Django. Каждая статья написана как отдельное руководство по одному из аспектов разработки Django, призванное помочь фронтенд-разработчикам и дизайнерам глубже понять «другую половину» кодовой базы. Эти статьи в основном созданы для того, чтобы помочь вам понять теорию и соглашения, но содержат некоторые примеры кода, написанные на Django 3.0. Несколько концепций, которые мы затронули в этой статье, включая шаблоны, пользователей-администраторов, модели и формы, будут подробно рассмотрены по отдельности в следующих статьях этой серии.
Дальнейшие части в серии:
- Django Highlights: создание шаблонов строк сохранения (часть 2)
- Особенности Django: модели, администрирование и использование реляционной базы данных (часть 3)
- Основные моменты Django: работа со статическими активами и медиафайлами (часть 4)