Вопрос по symfony – Перенаправить, если пользователь вошел в систему

14

Я создаю веб-приложение с Symfony 2, используя пакет FOSUserBundle.
Пользователи создают учетную запись, войдите в систему и начните использовать приложение.

Чего я хочу сейчас добиться - это перенаправить пользователя в свою учетную запись с любой страницы, на которой он может находиться, если он вошел в систему.
Это включает

если они вернутся на страницу входа если они вернутся на страницу регистрации если они перейдут на домашнюю страницу сайта раз они подтверждают свою электронную почту раз они сбросили свой пароль

В основном код будет выглядеть примерно так:

<code>$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));
    }
}
</code>

Проблема в том, что я не знаю, куда этот код должен идти.
Это должно быть выполнено для любого запроса. В Symfony 1 я бы использовал фильтр.

Ваш Ответ

2   ответа
31

Я сам нашел решение:

<?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 ]  
Не рекомендуется внедрять контейнер в службу, вы можете добавить службу security.context. Benjamin Lazarecki
@ benjamin Это даже проще, чем это. Поскольку @dan нужен объект запроса, он может извлечь его из события через$event->getRequest(). Видеть: Stackoverflow.com / а / 11506088/838733, Symfony.com / док / ток / кулинарной / event_dispatcher / ... или Github.com / Symfony / Symfony / BLOB / 2,0 / SRC / Symfony / Component / ... nietonfir
1

если вы хотите просто проверить один раз:

При каждом успешном входе в систему происходит событие. Событие названо:

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>

in 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) {

}

Похожие вопросы