Создание формы логина на Symfony
Итак, мы уже сделали с вами регистрацию, научились отправлять письма на почту. Осталось реализовать формы входа и выхода, чтобы наше приложение было достаточно защищенным.
Пожалуй, это будет самая короткая статья из этой серии, ведь Symfony предлагает крайне простой механизм создания Login и Logout действий.
Для начала создайте контроллер SecurityController. Он будет достаточно простым и содержать два действия login и logout, поэтому нет необходимости наследоваться от Controller. Все нужно мы заинжектим через конструктор, а нужен нам только twig для рендера формы. Вот как будет выглядеть наш контроллер в самом начале:
<?php
declare(strict_types=1);
namespace App\Controller;
use Twig_Environment;
class SecurityController
{
/**
* @var Twig_Environment $twig
*/
private $twig;
public function __construct(
Twig_Environment $twig
) {
$this->twig = $twig;
}
}
Теперь реализуем первый action - login.
/**
* @Route("/login", name="login")
*/
public function login(AuthenticationUtils $authenticationUtils)
{
$lastUsername = $authenticationUtils->getLastUsername();
$error = $authenticationUtils->getLastAuthenticationError();
return new Response($this->twig->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error
])
);
}
На самом деле, это все. Вам не нужно писать действия по проверке схожести паролей, логина, доставать пользователя из базы или стартовать сессию. Если вы помните, в уроке по созданию сущности (первая статья из серии по реализации аутентификации) мы уже подготовили конфигурацию для логина в файлу config/packages/security.yaml. Она выглядела следующим образом:
providers:
database_users:
entity:
class: App\Entity\User
property: email
Так мы создали простой провайдер, который знает, как достать пользователя по определенному полю (в нашем случае этим полем является email).
Компонент AuthenticationUtils отдает нам пользователя либо из сессии, если он уже вошел, или из базы. Также отдает ошибку при входе. Оба этих поля мы передаем в следующий шаблон:
{% extends 'base.html.twig' %}
{% block body %}
{% if error %}
<div class="alert alert-danger">
{{ error.message }}
</div>
{% endif %}
<div class="container" style="padding-top: 160px ">
<form method="post">
<div class="form-group">
<input type="text" name="_username" required="required" class="form-control" id="exampleInputEmail1">
<small id="emailHelp" class="form-text text-muted">Введите электронный адрес</small>
</div>
<div class="form-group">
<input type="password" name="_password" required="required" class="form-control" id="exampleInputPassword1">
</div>
<button type="submit" class="btn btn-primary">Войти</button>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
</form>
</div>
{% endblock %}
Нам даже не нужно указывать атрибут "action" в теге form, достаточно указать поля name="_username" и name="_password".
Не забудем про CSRF-защиту от автоподбора, которая генерирует уникальный хэш при каждой авторизации:
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
Также выведем ошибки в блоке сверху:
{% if error %}
<div class="alert alert-danger">
{{ error.message }}
</div>
{% endif %}
Теперь напишем action - logout. Выглядеть он будет следующим образом:
/**
* @Route("/logout", name="logout")
*/
public function logout()
{
}
Вы поверите, если я скажу, что на этом все? Но это правда так. Вернее, не совсем. Symfony уже знает, как разлогинить пользователя, достаточно правильно настроить config/packages/security.yaml.
firewalls:
main:
form_login:
check_path: login
login_path: login
default_target_path: homepage
logout:
path: logout
Это стандартная настройка, которая, на мой взгляд, достаточно красноречива: login_path - это страница входа, куда перенаправляется пользователь, когда хочет получить доступ к страницам с определенными правами доступа; default_target_path - это роут, куда перенаправляется пользователь после входа; path: logout - это имя экшена, который разлогинивает пользователя; check_path - это роут, который ловит login-запросы.
На этом все. Вот так просто реализуется авторизация в Symfony.
Комментарии