Pergunta sobre symfony – Redirecionar se o usuário está logado

14

Eu estou construindo uma aplicação web com o Symfony 2, usando o pacote FOSUserBundle.
Os usuários criam uma conta, fazem o login e começam a usar o aplicativo.

O que eu quero alcançar agora é redirecionar o usuário para sua conta de qualquer página em que ele possa estar se estiver logado.
Isso inclui:

se eles voltarem para a página de loginse eles voltarem para a página de registrose eles vão para a página inicial do siteuma vez que eles confirmam o seu emailuma vez que eles redefinir sua senha

Basicamente, o código seria algo assim:

<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>

O problema é que eu não sei onde esse código deve ir.
Deve ser executado para qualquer pedido. No Symfony 1 eu teria usado um filtro.

Sua resposta

2   a resposta
31

Eu mesmo encontrei a solução:

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

E então, no arquivo services.yml do meu pacote:

<code>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 ]  
</code>
Não é recomendável injetar o contêiner em um serviço, você pode injetar o serviço security.context. Benjamin Lazarecki
@benjamin É ainda mais simples que isso. Como @dan precisa do objeto request, ele pode recuperá-lo do evento via$event->getRequest(). Vejo:stackoverflow.com/a/11506088/838733, symfony.com/doc/current/cookbook/event_dispatcher/… ougithub.com/symfony/symfony/blob/2.0/src/Symfony/Component/… nietonfir
1

Há um evento acionado sempre que um login bem-sucedido é feito.O evento é nomeado:

security.interactive_login

Para se inscrever neste evento, você deve criar um container de serviço com sua classe criada, digamos "LoginListener.php" e injetar a tag "kernel.even_listener" com o evento "security.interactive_login":

<code><service id="mylogin.success.listener" class="path\to\class\LoginListener">
   <tag name="kernel.event_listener" event="security.interactive_login" method="onLoginSuccess" />
</service>
</code>

em LoginListener:

<code>use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

public function onLoginSuccess(InteractiveLoginEvent $event) {
   if ($this->_security->isGranted('IS_AUTHENTICATED_FULLY')) {
      //your code here...
   }
}
</code>

você também pode adicionar outras dependências e injetar no construtor, no meu caso eu tive que injetar segurança, sessão e container:

<code>public function __construct(SecurityContext $security, Session $session,            ContainerInterface $container) {

}
</code>

Perguntas relacionadas