如果用户已登录,则重定向

dan*_*dan 14 symfony

我正在使用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));
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我不知道该代码应该去哪里.
它应该针对任何请求执行.在Symfony 1中我会使用过滤器.

dan*_*dan 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));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在我的bundle的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 ]  
Run Code Online (Sandbox Code Playgroud)

  • 不建议在服务中注入容器,您可以注入security.context服务. (14认同)
  • @benjamin它甚至比那更简单.由于@dan需要请求对象,他可以通过`$ event-> getRequest()`从事件中检索它.请参阅:http://stackoverflow.com/a/11506088/838733,http://symfony.com/doc/current/cookbook/event_dispatcher/before_after_filters.html#after-filters-with-the-kernel-response-event或https://github.com/symfony/symfony/blob/2.0/src/Symfony/Component/HttpKernel/Event/KernelEvent.php (8认同)