14

我正在使用 FOSUserBundle 包构建一个带有 Symfony 2 的 Web 应用程序。
用户创建一个帐户,登录并开始使用该应用程序。

我现在想要实现的是让用户从他们登录后可能位于的任何页面重定向到他们的帐户。
这包括:

  • 如果他们回到登录页面
  • 如果他们回到注册页面
  • 如果他们访问网站的主页
  • 一旦他们确认了他们的电子邮件
  • 一旦他们重置密码

基本上代码是这样的:

$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 中,我会使用过滤器。

4

2 回答 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 ]  
于 2012-05-09T08:42:21.223 回答
1

如果您只想检查一次,也可以执行此解决方案:

每次成功登录时都会触发一个事件。 活动名称:

security.interactive_login

为了订阅这个事件,你必须用你创建的类创建一个服务容器,比如说“LoginListener.php”,并用事件“security.interactive_login”注入标签“kernel.even_listener”:

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

在登录监听器中:

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

}
于 2014-03-07T07:09:31.377 回答