Добрый вечер. Как можно "автоматически перенаправить" пользователя в область /account, когда у него есть роль, например, ROLE_USER, поэтому, когда он аутентифицирован/вошел в систему? (Не анонимно)
Я хочу, чтобы пользователь не получал доступ к "стандартным" страницам пользователя fos:
Форма "Форма входа", "Регистрационная форма" и "Сброс пароля",
когда он вошел в систему. Это не имеет смысла для меня, если пользователь уже вошел в систему и может войти в систему во второй раз или сбросить пароль или зарегистрироваться еще раз..
Каков наилучший подход к этому?
С уважением
Расширяя свой ответ в комментариях.
Лучший подход, который я могу придумать, - послушать событие kernel.controller
. Затем в этом случае проверьте, находится ли контроллер в списке контроллера черного списка, чтобы решить, следует ли пересылать пользователя в виде исключения.
EventSubscriber
Это будет прослушивать событие kernel.controller
. Затем он проверяет, является ли контроллер одним из 3 контроллеров FOSUserBundle, которые вы хотите пропустить, если пользователь вошел в систему. Если контроллер является одним из них, то генерируется исключение, которое затем kernel.exception
событием kernel.exception
. Если исключение указано, то вы пересылаете пользователя на маршрут, указанный в ответе на перенаправление.
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 }
Вы можете создать прослушиватель, который будет прослушивать IntercativeLoginEvent. Когда это произойдет, вы можете проверить, какая роль имеет аутентифицированный пользователь и перенаправить его туда, где вы хотите, чтобы он был перенаправлен.
Посмотрите на эти страницы:
http://symfony.com/doc/current/components/security/authentication.html http://www.webtipblog.com/create-authentication-listener-symfony-2/
Надеюсь, поможет.
FOSUserEvents::REGISTRATION_INITIALIZE
хотя это не поможет для установки пароля, поскольку не создает событие. Лучшим способом было бы прослушать событиеkernel.controller
для этих 3 контроллеров, и, если пользователь вошел в систему, сгенерировать исключение, которое можно затем перехватить в событииkernel.exception
для последующего перенаправления. Когда у меня будет больше времени, я смогу продолжить.