Шаг 15: Защита административной панели
Защита административной панели¶
Административная панель должна быть доступна только доверенным лицам. Защитить её можно с помощью компонента Symfony Security.
Как и Twig, компонент безопасности был уже установлен через промежуточные зависимости. Тем не менее, укажем его явно в файле composer.json
:
1 | $ symfony composer req security
|
Определение сущности для пользователей¶
Несмотря на то, что посетители не смогут создавать учётные записи на сайте самостоятельно, мы создадим полнофункциональную систему аутентификации для администратора. Поэтому у нас будет только один пользователь — администратор сайта.
На первом шаге давайте определим сущность User
. Чтобы избежать возможной путаницы, назовём её Admin
.
Для интеграции сущности Admin
с системой аутентификации Symfony Security, она должна соответствовать определённым требованиям. Например, наличие свойства password
является обязательным.
Для создания сущности Admin
выполните специальную команду make:user
вместо обычной make:entity
.
1 | $ symfony console make:user Admin
|
Ответьте на вопросы в терминале: использовать ли Doctrine для хранения администраторов (yes
), какое из свойств использовать для отображения имени администратора (username
), должен ли каждый пользователь иметь пароль (yes
).
Созданный класс содержит методы вроде getRoles()
, eraseCredentials()
и многие другие, необходимые Symfony для системы аутентификации.
Используйте команду make:entity
, если вам нужно добавить дополнительные свойства в сущность Admin
.
Также давайте добавим метод __toString()
, так как его использует EasyAdmin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | --- a/src/Entity/Admin.php
+++ b/src/Entity/Admin.php
@@ -75,6 +75,11 @@ class Admin implements UserInterface
return $this;
}
+ public function __toString(): string
+ {
+ return $this->username;
+ }
+
/**
* @see UserInterface
*/
|
Помимо создания самой сущности Admin
, команда также обновит конфигурацию безопасности и свяжет сущность с системой аутентификации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | --- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -1,7 +1,15 @@
security:
+ encoders:
+ App\Entity\Admin:
+ algorithm: auto
+
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
- in_memory: { memory: null }
+ # used to reload user from session & other features (e.g. switch_user)
+ app_user_provider:
+ entity:
+ class: App\Entity\Admin
+ property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
Выбор наилучшего алгоритма для хеширования паролей (который со временем будет меняться) мы оставим на усмотрение Symfony.
Пришло время создать миграцию и применить её к базе данных:
1 2 | $ symfony console make:migration
$ symfony console doctrine:migrations:migrate -n
|
Создание пароля для администратора¶
Так как у нас будет всего лишь один администратор, мы не будем разрабатывать отдельную систему для создания администраторских учётных записей. В качестве логина используем admin
и захешируем пароль.
Придумайте любой пароль и при помощи следующей команды захешируйте его:
1 | $ symfony console security:encode-password
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Symfony Password Encoder Utility
================================
Type in your password to be encoded:
>
------------------ ---------------------------------------------------------------------------------------------------
Key Value
------------------ ---------------------------------------------------------------------------------------------------
Encoder used Symfony\Component\Security\Core\Encoder\MigratingPasswordEncoder
Encoded password $argon2id$v=19$m=65536,t=4,p=1$BQG+jovPcunctc30xG5PxQ$TiGbx451NKdo+g9vLtfkMy4KjASKSOcnNxjij4gTX1s
------------------ ---------------------------------------------------------------------------------------------------
! [NOTE] Self-salting encoder used: the encoder generated its own built-in salt.
[OK] Password encoding succeeded
|
Создание администратора¶
Добавьте администратора, используя следующий SQL-запрос:
1 2 3 | $ symfony run psql -c "INSERT INTO admin (id, username, roles, password) \
VALUES (nextval('admin_id_seq'), 'admin', '[\"ROLE_ADMIN\"]', \
'\$argon2id\$v=19\$m=65536,t=4,p=1\$BQG+jovPcunctc30xG5PxQ\$TiGbx451NKdo+g9vLtfkMy4KjASKSOcnNxjij4gTX1s')"
|
Обратите внимание на экранирование знака $
в столбце пароля; экранируйте их все!
Настройка аутентификации¶
Теперь, когда у нас есть пользователь с правами администратора, мы можем защитить административную панель. Symfony поддерживает несколько стратегий аутентификации. Давайте воспользуемся классической и достаточно популярной системой аутентификации с помощью формы.
Выполните команду make:auth
, чтобы обновить конфигурацию безопасности, сгенерировать шаблон с формой входа, а также создать аутентификатор (класс для управления аутентификацией):
1 | $ symfony console make:auth
|
Выберите 1
для создания аутентификатора с формой входа, назовите класс аутентификатора — AppAuthenticator
, контроллер — SecurityController
и ответьте yes
, чтобы добавить маршрут для выхода из системы по пути /logout
.
Для связывания вновь созданных классов, команда обновит настройки безопасности:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | --- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -16,6 +16,13 @@ security:
security: false
main:
anonymous: lazy
+ guard:
+ authenticators:
+ - App\Security\AppAuthenticator
+ logout:
+ path: app_logout
+ # where to redirect after logout
+ # target: app_any_route
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
|
Благодаря подсказке во время выполнения команды, для перенаправления пользователя в случае успешного входа, нам также необходимо изменить маршрут в методе onAuthenticationSuccess()
:
1 2 3 4 5 6 7 8 9 10 11 12 | --- a/src/Security/AppAuthenticator.php
+++ b/src/Security/AppAuthenticator.php
@@ -96,8 +96,7 @@ class AppAuthenticator extends AbstractFormLoginAuthenticator implements Passwor
return new RedirectResponse($targetPath);
}
- // For example : return new RedirectResponse($this->urlGenerator->generate('some_route'));
- throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
+ return new RedirectResponse($this->urlGenerator->generate('easyadmin'));
}
protected function getLoginUrl()
|
Совет
Как узнать, что для доступа к EasyAdmin необходимо использовать маршрут easyadmin
? Я не знаю. Но я запустил команду, которая показывает список всех доступных маршрутов вместе с их путями:
1 | $ symfony console debug:router
|
Добавление правил контроля доступа для авторизации¶
Система безопасности состоит из двух частей: аутентификация и авторизация . При создании администратора мы добавили ему роль ROLE_ADMIN
. Чтобы ограничить доступ к разделу /admin
только для пользователей имеющих эту роль, необходимо добавить правило в access_control
:
1 2 3 4 5 6 7 8 9 | --- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -34,5 +34,5 @@ security:
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- # - { path: ^/admin, roles: ROLE_ADMIN }
+ - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
|
Правила access_control
ограничивают доступ с помощью регулярных выражений. При переходе по URL-адресу, который начинается с /admin
, система безопасности проверит наличие роли ROLE_ADMIN
у авторизованного пользователя.
Аутентификация через форму входа¶
Теперь при открытии административной панели вы автоматически окажетесь на странице входа, где вам будет предложено ввести логин и пароль:

Войдите в систему, используя логин admin
и незашифрованный пароль, который был захеширован вами ранее. Если вы корректно скопировали мою SQL-команду, то пароль будет admin
.
Обратите внимание, что EasyAdmin автоматически распознает систему аутентификации Symfony:

Попробуйте нажать на ссылку «Sign out». Всё готово! Теперь у вас есть полностью защищённая административная панель.
Примечание
Если вы хотите создать полноценную систему аутентификации с использованием формы, используйте команду make:registration-form
.
- « Previous Шаг 14: Получение обратной связи с помощью форм
- Next » Шаг 16: Защита от спама с помощью API
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.