Аутентификация пользователя – важная составляющая процесса работы почти с любым сайтом. Довольно непросто выполнить качественную аутентификацию пользователя в Django, так еще чтобы она была безопасной. По ходу процесса постоянно будут появляться новые проблемы, связанные с безопасностью, и зачастую новичкам непросто справиться с ними самостоятельно. Хорошо, что в Django имеется встроенная система аутентификации пользователя, которую мы сейчас будем рассматривать подробнее.
Как выполняется аутентификация пользователя в Django?
В ходе работы с каждым новым проектом, Django по умолчанию ставит приложение auth, имеющий специальный объект с названием User. Он включает следующие поля:
- username;
- password;
- email;
- first_name;
- last_name.
Мы используем его для того, чтобы выполнить вход, выход и зарегистрировать человека в блоге на Django.
Django имеет LoginView для страницы входа по умолчанию. Нам необходимо лишь настроить:
- URL маршруты для реализации аутентификационной системы;
- HTML шаблон для создания страницы входа;
- обновить settings.py.
Сперва обновим blog_project/urls.py. Разместим страницы входа и выхода, используя префикс accounts. На предпоследней строчке есть маленькое добавление.
# blog_project/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('django.contrib.auth.urls')), # Добавили новый маршрут path('', include('blog.urls')), ]
Как описывается в LoginView документации, изначально Django будет осуществлять поиск файла login.html в директории registration. Следовательно, нам нужна новая директория с именем registration, а внутри создать требуемый файл шаблона HTML. Закройте локальный веб-сервер, воспользовавшись комбинацией Ctrl+c в командной строке. Затем пропишите следующее инструкции:
(blog) $ mkdir templates/registration (blog) $ touch templates/registration/login.html
Теперь используйте такой контент для файла.
<!-- templates/registration/login.html --> {% extends 'base.html' %} {% block content %} <h2>Log In</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Log In</button> </form> {% endblock content %}
HTML теги нами применяются для формы <form></form>, после чего указывается POST в качестве метода отправки. Ведь здесь необходимо отправить данные на сервер (если потребовалось запросить информацию, как вариант в процессе поиска, то использовался бы метод GET). Далее в форму добавляется следующий токен {% csrf_token %} для того, чтобы сделать приложение более безопасным. Зачем это нужно? Прежде всего, для предотвращения XSS атак.
Вывод содержимого формы будет осуществляться с использованием параграфа при помощи {{ form.as_p }}, а далее добавим кнопку «Log In».
На конечном этапе нам надо определить, куда конкретно следует перенаправить человека после удачного входа. Для этого испольузется переменная LOGIN_REDIRECT_URL. Внизу нашего файла settings.py добавляем строку, которая приведена во фрагменте кода ниже:
# blog_project/settings.py LOGIN_REDIRECT_URL = 'home'
Теперь человек, который посещает веб-сайт, будет направляться на URL-маршрут называющийся ‘home’. Это, собственно, и будет домашней страницей.
Все реально удалось! После того, как мы запустим локальный веб-сервер, используя команду Python manage.py runserver и перейдем после этого на страницу входа http://127.0.0.1:8000/accounts/login/ откроется следующее:
Вот, как будет выглядеть страница аутентификации человека, который заходит на вашу веб-страницу.
После того, как мы введем логин и пароль, будет выполнено перенаправление на домашнюю страницу.
Учтите, что нами не добавлялись никакие логические операции для представления, а также не создавались модели данных. Все необходимое предоставляется самой системой аутентификации Django.
Данные пользователя на главной странице
Давайте теперь немного обновим шаблон base.html так, чтобы посетители могли видеть сообщение вне зависимости от того, насколько успешно была ими пройдена аутентификация. Применим для этой цели атрибут is_authenticated.
Теперь необходимо лишь разместить такой код в соответствующем месте нашего шаблона. Давайте обновим файл base.html, вставив его под закрывающимся тегом </header>.
<!-- templates/base.html --> {% load static %} <html> <head> <title>Django blog</title> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400" rel="stylesheet"> <link href="{% static 'css/base.css' %}" rel="stylesheet"> </head> <body> <div> <header> <div class="nav-left"> <h1><a href="{% url 'home' %}">Django blog</a></h1> </div> <div class="nav-right"> <a href="{% url 'post_new' %}">+ New Blog Post</a> </div> </header> {% if user.is_authenticated %} <p>Hi {{ user.username }}!</p> {% else %} <p>You are not logged in.</p> <a href="{% url 'login' %}">Log In</a> {% endif %} {% block content %} {% endblock content %} </div> </body> </html>
Далее система поприветствует человека, который вошел в аккаунт. Иначе вы будете автоматически перенаправлены на страницу аутентификации.
Все получилось! Имя суперпользователя – wsv, и именно оно отображается на главной странице.
Выход пользователя из профиля на Django
Человеком была благополучно пройдена процедура аутентификации, но как реализовать выход из личного кабинета? Конечно, можно сразу зайти в админку и выйти оттуда. Тем не менее, есть вариант получше Добавим ссылку выхода, которая выполнит редирект посетителя на главную. Система аутентификации Django даст возможность добиться этого сценария с минимальными затратами времени и сил.
В файле base.html добавим линк {% url ‘logout’ %} для выхода непосредственно после приветствия человека.
<!-- templates/base.html--> ... {% if user.is_authenticated %} <p>Hi {{ user.username }}!</p> <p><a href="{% url 'logout' %}">Log out</a></p> {% else %} ...
Вот, фактически все, что нам нужно, ведь непосредственно представление осуществляется приложением auth от Django. Конечно, нам следует уточнить, куда конкретно пользователь направляется после выхода из аккаунта.
Обновим settings.py для создания ссылки перенаправления, которая будет называться LOGOUT_REDIRECT_URL. Мы можем добавить ее вместе со ссылкой для входа. Так файл будет выглядеть следующим образом:
# blog_project/settings.py LOGIN_REDIRECT_URL = 'home' LOGOUT_REDIRECT_URL = 'home' # Новое изменение
В ходе обновления домашней страницы мы увидим, что у пользователей, которые вошли в аккаунт, появилась ссылка «Log out».
После того, как мы нажмем на ссылку, которая появилась, вы будете автоматически перенаправлены на домашнюю страницу, где отобразится ссылка для входа.
А теперь попробуйте несколько раз зайти и выйти. Получается?
Как создать нового пользователя в Django?
Для создания пользователей потребуется представление (views). В Django предусмотрен для этого класс формы UserCreationForm, значительно упрощающий работу. По умолчанию в нем имеются три поля: username, password и password2.
Для разработки безопасной аутентификационной системы существует большое количество методов организации кода и URL маршрутов. Давайте создадим новое приложение accounts, специально для регистрационной страницы.
(blog) $ python manage.py startapp accounts
Псоле этого новое приложение добавляется в переменную INSTALLED_APPS из файла settings.py.
# blog_project/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog.apps.BlogConfig', 'accounts.apps.AccountsConfig', # Добавляем приложение тут ]
Затем добавляем новый URL маршрут в blog_project/urls.py, указывая на новое приложение прямо под тем местом, где нами было включено приложение auth.
# blog_project/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('accounts/', include('django.contrib.auth.urls')), path('accounts/', include('accounts.urls')), # новое добавление path('', include('blog.urls')), ]
Порядок URL маршрутов из переменной urlpatterns является значимым, поскольку файл читается сверху вниз. Соответственно, когда формируется запрос на URL-адрес /accounts/signup, Django сперва будет искать в django.contrib.auth.urls, и, не найдя такой, перейдет к приложению accounts.urls.
Двигаемся далее и формируем файл accounts/urls.py.
(blog) $ touch accounts/urls.py
Затем добавляем такой код в этот файл.
# accounts/urls.py from django.urls import path from .views import SignUpView urlpatterns = [ path('signup/', SignUpView.as_view(), name='signup'), ]
Теперь отправимся к представлению, что задействует встроенный класс UserCreationForm, и общий класс представления CreateView.
# accounts/views.py from django.contrib.auth.forms import UserCreationForm from django.urls import reverse_lazy from django.views import generic class SignUpView(generic.CreateView): form_class = UserCreationForm success_url = reverse_lazy('login') template_name = 'signup.html'
Теперь создадим HTML файл шаблона signup.html в нашу директорию templates:
(blog) $ touch templates/signup.html
После создания заполняем файл следующим кодом:
<!-- templates/signup.html --> {% extends 'base.html' %} {% block content %} <h2>Sign up</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Sign up</button> </form> {% endblock content %}
На этом все!