Перенаправление, если пользователь зарегистрирован
Я создаю веб-приложение с Symfony 2, используя пакет FOSUserBundle.
Пользователи создают учетную запись, регистрируются и начинают использовать приложение.
Теперь я хочу, чтобы пользователь перенаправлялся на свою учетную запись с любой страницы, на которой они могут быть, если они вошли в систему.
Это включает в себя:
- если они вернутся на страницу входа в систему
- если они вернутся на страницу регистрации
- если они перейдут на домашнюю страницу веб-сайта
- после подтверждения их электронной почты
- после их reset их пароля
В основном код будет примерно таким:
$container = $this->container;
$accountRouteName = "DanyukiWebappBundle_account";
if( $container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
// authenticated (NON anonymous)
$routeName = $container->get('request')->get('_route');
if ($routeName != $accountRouteName) {
return $this->redirect($this->generateUrl($accountRouteName));
}
}
Проблема в том, что я не знаю, куда должен идти этот код.
Он должен быть выполнен для любого запроса. В Symfony 1 я бы использовал фильтр.
Ответы
Ответ 1
Я нашел решение самостоятельно:
<?php
namespace Danyuki\UserBundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
class LoggedInUserListener
{
private $router;
private $container;
public function __construct($router, $container)
{
$this->router = $router;
$this->container = $container;
}
public function onKernelRequest(GetResponseEvent $event)
{
$container = $this->container;
$accountRouteName = "DanyukiWebappBundle_account";
if( $container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
// authenticated (NON anonymous)
$routeName = $container->get('request')->get('_route');
if ($routeName != $accountRouteName) {
$url = $this->router->generate($accountRouteName);
$event->setResponse(new RedirectResponse($url));
}
}
}
}
И затем, в файле services.yml моего пакета:
services:
kernel.listener.logged_in_user_listener:
class: Danyuki\UserBundle\Listener\LoggedInUserListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
arguments: [ @router, @service_container ]
Ответ 2
Вы также можете сделать это решение, если хотите просто проверить один раз:
Событие запускается каждый раз, когда выполняется успешный вход в систему.
Событие называется:
security.interactive_login
Чтобы подписаться на это событие, вам нужно создать контейнер службы с созданным классом, пусть скажет "LoginListener.php" и добавит тег "kernel.even_listener" к событию "security.interactive_login":
<service id="mylogin.success.listener" class="path\to\class\LoginListener">
<tag name="kernel.event_listener" event="security.interactive_login" method="onLoginSuccess" />
</service>
в LoginListener:
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
public function onLoginSuccess(InteractiveLoginEvent $event) {
if ($this->_security->isGranted('IS_AUTHENTICATED_FULLY')) {
//your code here...
}
}
вы также можете добавлять другие зависимости и вводить их в конструктор, в моем случае мне приходилось вводить безопасность, сеанс и контейнер:
public function __construct(SecurityContext $security, Session $session, ContainerInterface $container) {
}