Регистрации и аутентификации пользователя на Django

Регистрация пользователя в Django

К данному моменту мы создали блог на Django, который использует формы для создания, редактирования и удаления статей, однако главный элемент большинства веб-сайтов все еще отсутствует: аутентификация пользователя.

Содержание статьи

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

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

При создании любого нового проекта, Django по умолчанию устанавливает приложение auth. В нем есть объект User, содержащий такие поля как:

  • username;
  • password;
  • email;
  • first_name;
  • last_name.

Мы используем объект User для реализации входа, выхода и регистрации пользователя в блоге на Django.

Аутентификация пользователя в Django (LoginView)

По умолчанию, Django поставляется с представлением LoginView для страницы входа. Нам нужно только настроить:

  • URL маршруты для системы аутентификации;
  • создать HTML шаблон для страницы входа;
  • обновить файл settings.py.

Для начала обновим файл blog_project/urls.py. Поместим страницы для входа и для выхода на URL префиксе accounts. Небольшое добавление на предпоследней строке.

Как отмечается в документации к LoginView, по умолчанию Django будет искать файл login.html в папке registration. Таким образом, нам нужно создать новую директорию под названием registration, а внутри нее создать необходимый HTML файл шаблона. Закройте локальный веб-сервера, используя в командной строке комбинацию Control+c. После этого введите следующее команды:

Теперь наполните файл следующим контентом:

Мы используем HTML теги для формы <form></form> и указываем POST как метод отправки, так как здесь нужно будет отправить данные на сервер (в случае, если понадобилось запросить данные, например во время поиска, мы бы использовали метод GET). Добавляем в форму токен {% csrf_token %} в целях безопасности — по большей части для предотвращения XSS аттак. Содержимое формы выводится между тегами параграфа при помощи {{ form.as_p }}, после чего добавляется кнопка «Log In».

На финальном этапе нам нужно уточнить, куда именно перенаправить пользователя после успешного входа. Для этого настроем переменную LOGIN_REDIRECT_URL. В нижней части файла settings.py добавляем следующее:

Теперь пользователь будет направлен на URL-маршрут который имеет название 'home', который является домашней страницей.

Все действительно получилось! При новом запуске локального веб-сервера через команду python manage.py runserver и последующем переходе на страницу входа http://127.0.0.1:8000/accounts/login/ откроется следующее:

user account

Страница аутентификации для пользователя в Django

После ввода логина и пароля нашего аккаунта мы будем направлены на домашнюю страницу. Обратите внимание, что мы не добавляли никаких логических операции для представления и не создавали модели базы данных. Система аутентификации Django сама предоставляет все необходимое. Спасибо, Django!

Данные пользователя на главной странице | is_authenticated

Обновим шаблон base.html таким образом, чтобы пользователи могли увидеть сообщение вне зависимости от того, прошли они аутентификацию или нет. Для этого будем использовать атрибут is_authenticated.

Теперь нужно просто разместить следующий код в нужном месте нашего шаблона. Обновим файл base.html, вставив новый код под закрывающимся тегом </header>.

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

user account

Домашняя страница после аутентификации

Все сработало! Мое имя суперпользователя — wsv. Именно его я вижу на главной странице.

Выход пользователя из профиля на Django

Пользователь успешно прошел процедуру аутентификации, но… как теперь выйти? Можно было бы зайти в админку и выйти оттуда, однако есть способ получше. Добавим ссылку выхода, которая будет перенаправлять человека на домашнюю страницу. Благодаря системе аутентификации Django, добиться такого сценария проще простого.

В файле шаблона base.html добавим ссылку {% url 'logout' %} для выхода сразу после приветствия пользователя.

Вот и все, что от нас требуется, ведь само представление предоставляется приложением auth от Django. Правда, нам нужно уточнить, куда именно пользователь будет направлен после выхода из профиля.

Обновим settings.py для создания ссылки перенаправления, которая будет называться LOGOUT_REDIRECT_URL. Мы можем добавить ее рядом с ссылкой для входа, таким образом файл должен выглядеть следующим образом:

При обновлении домашней страницы можно увидеть, что у вошедших пользователей появилась ссылка для выхода «Log out«.

Django выход пользователя

Домашняя страница с ссылкой для выхода

После нажатия на появившуюся ссылку, вы будете перенаправлены на домашнюю страницу, где покажется ссылка для входа.

Страница выхода пользователя

Домашняя страница вышедшего пользователя

Попробуйте зайти и выйти несколько раз с вашим аккаунтом.

Регистрация нового пользователя в Django

Для регистрации новых пользователей также понадобится представление (views). В Django для этого предусмотрен класс формы UserCreationForm, который сильно упрощает работу. По умолчанию в нем присутствую три поля: username, password и password2.

Для создания надежной системы аутентификации предусмотрено множество способов организации кода и URL маршрутов. Сейчас мы создадим новое приложение accounts, специально для страницы регистрации.

Затем новое приложение добавляется в переменную INSTALLED_APPS из файла settings.py.

Далее добавляем новый URL маршрут в blog_project/urls.py, указывая на новое приложение прямо под тем местом, где мы включили приложение auth.

Порядок URL маршрутов из переменной urlpatterns имеет значение, так как Django читает файл сверху вниз. Следовательно, когда создается запрос на URL-адрес /accounts/signup, Django вначале будет искать в django.contrib.auth.urls, и, не найдя такой, перейдет к приложению accounts.urls.

Двигаемся далее и создаем файл accounts/urls.py.

И добавляем в него следующий код:

Мы используем пока не созданное представление под названием SignUpView, которое, если судить по наличию заглавных букв, является классовым представлением и имеет метод as_view(). Его URL-маршрут просто signup/, так что полный URL-маршрут будет accounts/signup/.

Теперь перейдем к представлению, что использует встроенный класс UserCreationForm, и общий класс представления CreateView.

Общий класс представления (generic) CreateView наследуется в классе SignUpView. Мы уточняем использование встроенного UserCreationForm и пока еще не созданного шаблона signup.html. Используем функцию reverse_lazy для перенаправления пользователя на страницу входа после успешной регистрации.

Зачем использовать reverse_lazy вместо reverse? Причина в том, что для всех общих классовых представлений URL не загружаются, когда имортируется файл. Поэтому нам нужно использовать функцию reverse_lazy для последующей загрузки URL, когда они будут доступны.

Теперь создадим HTML файл шаблона signup.html в нашу директорию templates:

После создания заполняем файл следующим кодом:

Формат очень похож на тот, что мы делали ранее. В верхней части мы расширяем базовый шаблон base.html, помещаем логические операции между тегами <form></form>, используем csrf_token в целях безопасности, отображаем содержимое формы используя form.as_p и добавляем кнопку подтверждения «Sign Up».

Все готово! Для проверки запустите локальный веб-сервер через python manage.py runserver и перейдите на недавно созданную страницу http://127.0.0.1:8000/accounts/signup/:

Страница регистрации в Django

Страница регистрации нового пользователя в Django

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

Мы создали нового пользователя с именем «william» и после регистрации нас перенаправили на страницу входа. После успешного ввода имени и пароля мы были направлен на персонализированную домашнюю страницу с приветствием в формате «Hi {username}».

Домашнаяя страница пользователя

Домашняя страница пользователя william

Общий порядок действий можно представить, как: Регистрация -> Аутентификация -> Домашняя страница. Конечно, мы можем внести сюда любые поправки. SignUpView перенаправляет на URL-маршрут с названием login, так как мы установили success_url = reverse_lazy('login'). Страница аутентификации перенаправляет на домашнюю страницу, так как в файле blog_project/settings.py мы установили LOGIN_REDIRECT_URL = 'home'.

Поначалу многообразие путей развития проекта Django может запутать. Это нормально. Со временем все выстроится в логичную цепочку действий.

Загружаем изменения на Github

С нашего последнего git коммита прошло много времени. Давайте выполним коммит, а затем загрузим копию кода на GitHub. Для начала посмотрим на всю выполненную работу через команду git status.

Добавляем все изменения в очередь на загрузку и описываем коротко, что из себя представляет данный коммит.

Создайте новое хранилище на GitHub, назвав его по своему усмотрению. Я выбрал название blog-app. После создания нового хранилища на GitHub можно выполнить следующие две команды. Не забудьте поменять в коде мое имя пользователя stillriverpress на свой никнейм.

Все готово! Теперь можно разместить новое приложение на Heroku.

Настраиваем Heroku для Блога на Django

Сейчас мы опубликуем приложение на Heroku уже в третий раз. Как и в случае с приложением доски объявления на Django, для использования Heroku потребуется сделать четыре изменения в файлах нашего блога.

  • обновить файл Pipfile.lock
  • создать новый файл Procfile
  • установить WSGI HTTP сервер Gunicorn
  • обновить файл settings.py

Уточняем Python версию в Pipfile, затем выполняем команду pipenv lock что приведет к созданию файла Pipfile.lock. Создаем файл Procfile, который является файлом конфигурации Heroku, устанавливаем gunicorn в качестве веб-сервера вместо локального веб-сервера Django и в конечном итоге обновляем переменную ALLOWED_HOSTS, чтобы приложение было видно каждому на просторе интернета.

Откройте файл Pipfile в текстовом редакторе и в нижней части добавьте две строчки:

Здесь мы указываем версию 3.7 вместо более точного 3.7.3. Приложение автоматически подстроится под текущую версию Python 3.7.x на Heroku.

Теперь запустите команду pipenv lock для обновления файла Pipfile.lock, так как Heroku использует его для генерации виртуального окружения на серверах Heroku для нашего приложения.

Создается новый файл Procfile.

Через текстовый редактор в Procfile добавьте следующую строчку:

Таким образом Heroku будет знать, что надо использовать Gunicorn в качестве веб-сервера, а не локальный веб-сервер от Django.

Теперь устанавливаем Gunicorn.

Наконец-то можно обновить переменную ALLOWED_HOSTS для разрешения всех доменов.

Теперь можно закоммитить новые изменения и перенести все на GitHub.

Запускаем Django Блог на Heroku

Для размещения проекта на Heroku сначала нужно подтвердить, что вы действительно вошли в свой аккаунт.

Затем введите команду create, которая говорит Heroku, что нужно сделать контейнер, в котором будет работать наше новое приложение. Если выполнить команду heroku create, то Heroku выдаст вам случайное имя суб-домена. Однако вы также можете настроить свое собственное имя суб-домена, только оно должно быть уникальным на Heroku. Другими словами, ввиду того, что я выбрал название dfb-blog, теперь оно для вас недоступно. Придется воспользоваться какой-то другой комбинацией букв и цифр.

Теперь настроим git, чтобы при размещении на Heroku было присвоено название вашего нового приложения (заменяете dfb-blog на выбранное вами название).

Остался еще один этап — нужно разобраться со статическими файлами, которые в нашем случае это CSS стили. На этапе продакшена Django не поддерживает оперирование статическими файлами, для этого можно использовать WhiteNoise. Давайте установим его.

Далее нам нужно обновить статические настройки для дальнейшей работы в продакшене. Через текстовый редактор откройте файл settings.py. Добавьте whitenoise к INSTALLED_APPS над встроенным приложением staticfiles, а также в переменой MIDDLEWARE на третьей строке. Порядок имеет значение как для INSTALLED_APPS, так и для MIDDLEWARE.

В нижней части файла добавьте новые строки кода для STATIC_ROOT и STATICFILES_STORAGE. Все должно выглядеть следующим образом.

Не забудьте добавить и закоммитить все новые изменения. Затем обновите проект на GitHub.

Наконец-то можно разместить код на Heroku и убедиться в том, что веб-приложение работает должным образом.

URL нашего нового приложения будет в выводе командной строки, имя домена можно получить через команду heroku open. Мой проект расположен на https://dfb-blog.herokuapp.com/.

user account

Блог на Heroku

Заключение

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