На предыдущем уроке мы реализовали механизм восстановления пароля, используя встроенные возможности Django. Для разработки мы применяли консольный почтовый бэкенд, который просто выводил содержимое писем в терминал.
Однако в реальном проекте, таком как Cinemahub, этого недостаточно. Пользователь ожидает получить письмо:
- при восстановлении пароля;
- при регистрации (в будущем — подтверждение email);
- при важных уведомлениях (изменение данных, безопасность аккаунта).
Для этого Django должен уметь отправлять настоящие письма через почтовый сервер. В этом уроке мы настроим отправку email через SMTP-протокол и проверим, что восстановление пароля работает уже «по-настоящему».
SMTP (Simple Mail Transfer Protocol) — это стандартный протокол отправки электронной почты. Django не отправляет письма напрямую, а:
- формирует письмо (тема, текст, получатель);
- подключается к SMTP-серверу;
- аутентифицируется;
- передаёт письмо серверу, который доставляет его адресату.
В Django за это отвечает SMTP email backend:
django.core.mail.backends.smtp.EmailBackendДля учебного проекта мы будем использовать Яндекс.Почту, так как:
- она бесплатна;
- поддерживает SMTP и SSL;
- позволяет создавать пароли приложений;
- часто используется в реальных проектах.
Подход будет аналогичен для Gmail, Mail.ru, корпоративной почты и других SMTP-серверов.
Современные почтовые сервисы не разрешают вход по основному паролю из сторонних приложений. Вместо этого используются пароли приложений.
Перед их созданием убедимся, что доступ для почтовых клиентов разрешён:
- Открой Яндекс.Почту.
- Перейди в Настройки.
- Найди раздел Почтовые программы.
- Убедись, что доступ для почтовых клиентов включён.
Пример:
Если этот шаг пропустить, Django не сможет подключиться к SMTP-серверу.
Теперь создадим отдельный пароль, который Django будет использовать для отправки писем.
- Перейди в Яндекс ID: https://id.yandex.ru/security/app-passwords
- Выбери тип приложения — Почта.
- Укажи название, например:
cinemahub-django - Яндекс сгенерирует пароль.
Важно:
- этот пароль показывается только один раз;
- сохрани его сразу — восстановить его нельзя, только создать новый.
Открой файл settings.py проекта Cinemahub и добавь настройки email.
# settings.py
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.yandex.ru"
EMAIL_PORT = 465
EMAIL_USE_SSL = True
EMAIL_HOST_USER = "адрес_почты@yandex.ru"
EMAIL_HOST_PASSWORD = "пароль_приложения"
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER- EMAIL_BACKEND — указывает Django использовать SMTP;
- EMAIL_HOST — SMTP-сервер Яндекса;
- EMAIL_PORT — порт для SSL-соединения;
- EMAIL_USE_SSL — включает шифрование;
- EMAIL_HOST_USER — email, от имени которого отправляются письма;
- EMAIL_HOST_PASSWORD — пароль приложения;
- DEFAULT_FROM_EMAIL — адрес отправителя по умолчанию.
Причины:
- используется обычный пароль, а не пароль приложения;
- опечатка в EMAIL_HOST_USER;
- неверный SMTP-хост или порт.
Решение: проверь настройки и создай новый пароль приложения.
Возможные причины:
- письмо попало в «Спам»;
- домен отправителя выглядит подозрительно;
- почта получателя не существует.
Для тестов используй реальный почтовый ящик, к которому у тебя есть доступ.
Теперь проверим всю цепочку в контексте проекта Cinemahub.
Перейди в браузере по адресу:
http://127.0.0.1:8000/users/password-reset/
- введи email пользователя, который существует в базе;
- нажми кнопку «Сбросить пароль».
-
Django перенаправит тебя на страницу:
password-reset/done/ -
Открой почтовый ящик.
-
Найди письмо с темой вроде:
Password reset on 127.0.0.1:8000 -
Перейди по ссылке из письма.
-
Установи новый пароль.
-
Попробуй войти под новым паролем.
Если все шаги выполнены успешно — SMTP настроен корректно.
Повторить реализацию восстановления пароля.
- Зачем Django нужен SMTP-сервер?
- Почему нельзя использовать основной пароль почты?
- Что такое пароль приложения?
- За что отвечает EMAIL_BACKEND?
- В чём разница между console и smtp backend?
- Почему важно использовать SSL?
- Где проверять корректность работы SMTP?
- Почему письма могут попадать в «Спам»?
