Чтобы авторизоваться на сайте пользователь должен перейти по адресу /auth/login/ и заполнить форму:
- Имя пользователя
- Пароль
Если поля заполнены заполнено верно — происходит редирект, например, на главную страницу.
Форма авторизации
Механизм авторизации уже есть в классе LoginView. В файле users/urls.py перехватываем запрос, указываем для этого адреса обработчик LoginView, в настройках обработчика указываем имя шаблона и name для пути:
from django.contrib.auth.views import LoginView, LogoutView
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('signup/', views.SignUp.as_view(), name='signup'),
path(
'logout/',
LogoutView.as_view(template_name='users/logged_out.html'),
name='logout'
),
path(
'login/',
LoginView.as_view(template_name='users/login.html'),
name='login'
),
]
Шаблон страницы авторизации будет таким:
# templates/users/login.html
{% extends "base.html" %}
{% block title %}Войти{% endblock %}
{% block content %}
{% load user_filters %}
<div class="row justify-content-center">
<div class="col-md-8 p-5">
<div class="card">
<div class="card-header">
Войти на сайт
</div>
<div class="card-body">
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
{{ error|escape }}
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
{{ error|escape }}
</div>
{% endfor %}
{% endif %}
<form method="post"
{% if action_url %}
action="{% url action_url %}"
{% endif %}
>
{% csrf_token %}
{% for field in form %}
<div class="form-group row my-3"
{% if field.field.required %}
aria-required="true"
{% else %}
aria-required="false"
{% endif %}
>
<label for="{{ field.id_for_label }}">
{{ field.label }}
{% if field.field.required %}
<span class="required text-danger">*</span>
{% endif %}
</label>
<div>
{{ field|addclass:'form-control' }}
{% if field.help_text %}
<small id="{{ field.id_for_label }}-help" class="form-text text-muted">
{{ field.help_text|safe }}
</small>
{% endif %}
</div>
</div>
{% endfor %}
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
Войти
</button>
<!-- Тест на внимательность. Без переопределения шаблона этого адреса
не существует. Нужно что-то делать, иначе все упадет -->
<a href="{% url 'users:password_reset_form' %}" class="btn btn-link">
Забыли пароль?
</a>
</div>
</form>
</div> <!-- card body -->
</div> <!-- card -->
</div> <!-- col -->
</div> <!-- row -->
{% endblock %}
Финальные настройки
Осталось объяснить Django, какие страницы надо показывать пользователю после входа в аккаунт и при выходе из него. Добавьте в yatube/settings.py такие настройки:
# yatube/settings.py
LOGIN_URL = 'users:login'
LOGIN_REDIRECT_URL = 'posts:index'
# LOGOUT_REDIRECT_URL = 'posts:index'
Эти константы указывают адреса страниц, на которые пользователь будет перенаправлен в той или иной ситуации. Если константы не указаны явно — будут применены значения по умолчанию.
- LOGIN_URL
Значение по умолчанию:'/accounts/login/'
Это адрес, на который Django будет перенаправлять пользователей для авторизации. Это особенно важно при использовании декоратора @login_required, о котором вы узнаете в следующих уроках (интрига).
- LOGIN_REDIRECT_URL
Значение по умолчанию:'/accounts/profile/'
Здесь указывается, куда перенаправить пользователя после успешной авторизации.
- LOGOUT_REDIRECT_URL
Значение по умолчанию:'/auth/logout/'
Адрес, на который будет направлен пользователь после выхода из системы. Можно оставить штатный, а можно раскомментировать строкуLOGOUT_REDIRECT_URL = 'posts:index'
— и при выходе из аккаунта пользователи будут перенаправляться на главную страницу проекта.
Страница с формой для изменения пароля
Создайте страницу с формой смены пароля. Поля формы:
- текущий пароль,
- новый пароль,
- новый пароль (повторно).
Адрес страницы для смены пароля: /auth/password_change/. Адрес страницы с сообщением об успешной смене пароля (если все получилось): /auth/password_change/done/.
Восстановление пароля по e-mail
Тут процесс посложнее. В шаблоне формы авторизации есть ссылка на /auth/password_reset/
, ведущая на шаблон с формой «восстановить пароль по email».Если через форму отправить email-адрес зарегистрированного пользователя — на этот адрес придёт письмо со ссылкой на восстановление пароля. При отправке этой формы пользователь перенаправляется на адрес /auth/password_reset/done/: там ему показывается сообщение о том, что письмо отправлено.
При переходе по ссылке из письма (ссылка будет примерно такого вида: /auth/reset/Mw/5si-f7ab5e9f2a875e9b7c61/), пользователь попадёт на форму создания нового пароля.Поля формы:
- Новый пароль
- Подтверждение нового пароля
После отправки этой формы пользователь перенаправляется на /auth/reset/done/: на этой странице он увидит оповещение о том, что пароль успешно изменён.
Подсказки
- Обратите внимание: код шаблонов очень похож. Стоит подумать про использование тегов {% include %} для оптимизации.
- Страница с формой для создания нового пароля: auth/reset/<uidb64>/<token>/ Пользователь попадает на эту страницу по ссылке из письма.
Ссылка в письме может сработать только один раз. Если пользователь перейдёт по ней, ссылка устареет. Для проверки «дееспособности» ссылки нужно добавить проверку переменной validlink. В зависимости от результата проверки должен показываться разный контент:
{% extends "base.html" %}
{% block title %}Новый пароль{% endblock %}
{% block content %}
{% load user_filters %}
{% if validlink %}
<!-- Тут код формы из шаблона -->
{% else %}
<div class="row justify-content-center">
<div class="col-md-8 p-5">
<div class="card">
<div class="card-header">Ошибка</div>
<div class="card-body">
<p>Ссылка сброса пароля содержит ошибку или устарела.</p>
</div> <!-- card body -->
</div> <!-- card -->
</div> <!-- col -->
</div> <!-- row -->
{% endif %}
{% endblock %}
А можно узнать как в итоге было сделано задание?
Переопределите шаблон авторизации в проекте Yatube. Это потребуется в финальном задании спринта.