Symfony 2.5.7 автоматическое перенаправление, когда пользователь аутентифицирован / зарегистрирован

0

Добрый вечер. Как можно "автоматически перенаправить" пользователя в область /account, когда у него есть роль, например, ROLE_USER, поэтому, когда он аутентифицирован/вошел в систему? (Не анонимно)

Я хочу, чтобы пользователь не получал доступ к "стандартным" страницам пользователя fos:

Форма "Форма входа", "Регистрационная форма" и "Сброс пароля",

когда он вошел в систему. Это не имеет смысла для меня, если пользователь уже вошел в систему и может войти в систему во второй раз или сбросить пароль или зарегистрироваться еще раз..

Каков наилучший подход к этому?

С уважением

  • 1
    Это то, что вы ищите? stackoverflow.com/questions/20190289/...
  • 0
    Вы можете сделать что-то вроде того, что я ответил здесь ( stackoverflow.com/a/24310957/1791606 ) с добавленным событием FOSUserEvents::REGISTRATION_INITIALIZE хотя это не поможет для установки пароля, поскольку не создает событие. Лучшим способом было бы прослушать событие kernel.controller для этих 3 контроллеров, и, если пользователь вошел в систему, сгенерировать исключение, которое можно затем перехватить в событии kernel.exception для последующего перенаправления. Когда у меня будет больше времени, я смогу продолжить.
Показать ещё 1 комментарий
Теги:
authentication
redirect

2 ответа

1
Лучший ответ

Расширяя свой ответ в комментариях.

Лучший подход, который я могу придумать, - послушать событие 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 }
  • 0
    Хороший, спасибо. Что вы думаете о моем подходе: проверка в indexAction действий FOS-контроллеров, если пользователь полностью аутентифицирован или нет. Если он есть, я перенаправляю его в «учетную запись», если нет, то шаблон для входа, например, отображается? С уважением
  • 0
    Это будет работать, так что это не так, я просто не думаю, что это самый чистый способ сделать это. Моими основными проблемами было бы то, что вам пришлось бы расширять / переопределять каждый из контроллеров по отдельности, что также означало бы необходимость использования дочернего комплекта для FOSUserBundle (если вы уже используете один из них, это не так уж и сложно). Это также приведет к небольшому повторению кода, так как это будет то же самое в каждой из операций indexActions. Кроме того, благодаря подходу, который я дал, вы также можете легко расширить его для использования интерфейсов с парой строк кода, чтобы охватить идеи @ Alex.
Показать ещё 2 комментария
0

Вы можете создать прослушиватель, который будет прослушивать IntercativeLoginEvent. Когда это произойдет, вы можете проверить, какая роль имеет аутентифицированный пользователь и перенаправить его туда, где вы хотите, чтобы он был перенаправлен.

Посмотрите на эти страницы:

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

Надеюсь, поможет.

  • 0
    Привет, я думаю, что это не то, что я ищу, потому что слушатель будет означать, что пользователь может получить доступ к сайту, и когда он пытается зарегистрироваться, я перенаправляю его. Я думаю, что я проверю в контроллере indexAction, например, RegistrationController, если у пользователя есть роль анонимно, и если нет, я перенаправлю его в свой профиль.
  • 0
    Вы можете реализовать интерфейс (скажем, LimitedAccessInterface), который будет реализовывать каждый контроллер, к которому у вас есть ограниченный доступ. А в слушателе вы можете проверить, реализует ли запрошенный контроллер LimitedAccessInterface, и у пользователя нет соответствующих разрешений, вы выбросите исключение или вернете RedirectResponse или все, что вам нужно. Конечно, вы можете проверить это прямо в своем действии, но что, если вам нужно реализовать это в нескольких местах? С интерфейсом вы можете просто добавить интерфейс к контроллеру и все. Вы не используете FOSUserBundle, поэтому я не предлагаю вам взглянуть на следующее предложение))
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню