nova.cp
nova.cp

Reputation: 455

Symfony 2.5.7 auto redirect when user is authenticated / logged

Good evening, How is it possible to "auto-redirect" a user to the /account area, when he has the role e.g. ROLE_USER, so when he is authenticated / has logged in ? (Not anonymously)

I want to prevent the user to get access to the "standard" fos userbundle pages :

The "login form", "registration form" and "password reset" form,

when he is logged in That doesn't make sense for me if the user is already logged in and can log in a second time or reset his password or register again..

What is the best approach to handle that?

Regards

Upvotes: 0

Views: 932

Answers (2)

qooplmao
qooplmao

Reputation: 17759

Expanding on my answer in the comments.

The best approach that I can think off would be to listen for the kernel.controller event. Then in this event check whether the controller is in your list of blacklisted controller to decide whether or not to forward your user by way of exception.

EventSubscriber

This will listen for the kernel.controller event. It will then check whether the controller is one of the 3 FOSUserBundle controller that you want to miss if the user is logged in. If the controller is one of those then an exception is thrown which is then caught by the kernel.exception event. If the exception is the one specified then you forward the user to the route that you state in the redirect response.

namespace Acme\UserBundle\EventSubscriber;

use Acme\UserBundle\Exception\FOSUserRedirectException;
use FOS\UserBundle\Controller\RegistrationController as FOSRegistrationController;
use FOS\UserBundle\Controller\ResettingController as FOSResettingController;
use FOS\UserBundle\Controller\SecurityController as FOSSecurityController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;

class FOSUserRedirectSubscriber implements EventSubscriberInterface
{
    protected $securityContext;

    protected $router;

    public function __construct(
        SecurityContextInterface $securityContext,
        UrlGeneratorInterface $router
    ) {
        $this->securityContext = $securityContext;
        $this->router = $router;
    }

    public static function getSubscribedEvents()
    {
        return array(
            KernelEvents::CONTROLLER    => 'onKernelController',
            KernelEvents::EXCEPTION     => 'onKernelException',
        );
    }

    /**
     * Check to see whether current user is logged in
     * If controller is one of specified throw FOSUserRedirectException
     *
     * @param FilterControllerEvent $event
     * @throws FOSUserRedirectException
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType() ||
            !$this->securityContext->isGranted('ROLE_USER')
        ) {
            return;
        }

        $controller = $event->getController();

        if ($controller[0] instanceof FOSRegistrationController ||
            $controller[0] instanceof FOSResettingController ||
            $controller[0] instanceof FOSSecurityController
        ) {
            throw new FOSUserRedirectException();
        }
    }

    /**
     * If user is logged in but has loaded one of the specified
     * FOSUserBundle controllers
     *
     * @param GetResponseForExceptionEvent $event
     */
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $exception = $event->getException();

        if (!$exception instanceof FOSUserRedirectException) {
            return;
        }

        $url = $this->router->generate('**THE_ROUTE_YOU_WISH_TO_REDIRECT_TO**');
        $response = new RedirectResponse($url);

        $event->setResponse($response);
    }
}

Exception

namespace Acme\UserBundle\Exception;

class FOSUserRedirectException extends \Exception
{

}

service.yml

parameters:
    acme_user.subscriber.fos_redirect.class: Acme\UserBundle\EventSubscriber\FOSUserRedirectSubscriber

services:
    acme_user.subscriber.fos_redirect:
        class: %acme_user.subscriber.fos_redirect.class%
        arguments:
            - @security.context
            - @router
        tags:
            - { name: kernel.event_subscriber }

Upvotes: 1

Alex
Alex

Reputation: 1183

You can create a listener which will listen IntercativeLoginEvent. When it happens you can check which role has the authenticated user and redirect him wherever you want him to be redirected.

Look at these pages:

http://symfony.com/doc/current/components/security/authentication.html http://www.webtipblog.com/create-authentication-listener-symfony-2/

Hope, it helps.

Upvotes: 0

Related Questions