使用FOSUserBundle将用户角色重定向到一个不同的主页上[英] redirect to a different homepage following user role using FOSUserBundle

本文是小编为大家收集整理的关于使用FOSUserBundle将用户角色重定向到一个不同的主页上的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在我的Symfony应用程序中,我正在使用fosuserbundle.

这是一个应用程序,涉及用户的两个主要角色:工厂为ROLE_FACTORY和custommer as ROLE_CUSTOMER.

我有一个针对非连接用户的主页,它是应用程序的主页.

但是,当用户要连接或连接时,遵循他的角色,主页必须更改.

因此,FOS用户登录操作必须重定向到正确的页面.

ROLE_FACTORY必须重定向到factory_homepage路线. ROLE_CUSTOMER必须重定向到customer_homepage路线.

如何在最佳实践中创建此行为使用Symfony和FOSUSerBundle.

推荐答案

首先没有最好的做法.因此,我将选择这些选项之一的决定留给您,无论根据您的需求哪种适合您.

选项1:

在这种情况下,您必须实现EventListener.

步骤1)

注册服务

<service id="acme_demo.listener.login" class="Acme\DemoBundle\EventListener\LoginListener" scope="request">
    <tag name="kernel.event_listener" event="security.interactive_login" method="onSecurityInteractiveLogin"/>
    <argument type="service" id="router"/>
    <argument type="service" id="security.context"/>
    <argument type="service" id="event_dispatcher"/>
</service>

步骤2)

您的EventListener本身

class LoginListener
{
    protected $router;
    protected $security;
    protected $dispatcher;

    public function __construct(Router $router, SecurityContext $security, EventDispatcher $dispatcher)
    {
        $this->router = $router;
        $this->security = $security;
        $this->dispatcher = $dispatcher;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
    }

    public function onKernelResponse(FilterResponseEvent $event)
    {
        if ($this->security->isGranted('ROLE_FACTORY')) 
        {
            $response = new RedirectResponse($this->router->generate('factory_homepage'));
        } 
        elseif ($this->security->isGranted('ROLE_CUSTOMER')) 
        {
            $response = new RedirectResponse($this->router->generate('customer_homepage'));
        } 
        else 
        {
            $response = new RedirectResponse($this->router->generate('default_homepage'));
        }

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

选项2:

您可以通过loginAction看起来像

public function loginAction(Request $request)
{
    $securityContext = $this->container->get('security.context');
    $router = $this->container->get('router');

    if ($securityContext->isGranted('ROLE_FACTORY')) 
    {
        return new RedirectResponse($router->generate('factory_homepage'));
    }
    elseif ($securityContext->isGranted('ROLE_CUSTOMER')) 
    {
        return new RedirectResponse($router->generate('customer_homepage'));
    }
    else
    {
        return new RedirectResponse($router->generate('default_homepage'));
    }
}

本文地址:https://www.itbaoku.cn/post/2090852.html

问题描述

In my Symfony application I am using the FOSUserBundle.

It's an application involved two main Roles of User: Factory as ROLE_FACTORY and Custommer as ROLE_CUSTOMER.

I have a main page for non-connected user, it's the home page of the application.

But when User is going to be connected or is connected, following the role he has, the home page has to change.

So the fos user login action have to redirect to the right page.

ROLE_FACTORY have to be redirect to the factory_homepage route. ROLE_CUSTOMER have to be redirect to the customer_homepage route.

How can I create this behavior in the best practice using Symfony and FOSUSerBundle.

推荐答案

First off there is no best practice for this. So I leave that decision of selecting one of these options to you whichever suits you according to your needs.

OPTION 1:

You have to implement an EventListener in this case.

STEP 1)

Register a service

<service id="acme_demo.listener.login" class="Acme\DemoBundle\EventListener\LoginListener" scope="request">
    <tag name="kernel.event_listener" event="security.interactive_login" method="onSecurityInteractiveLogin"/>
    <argument type="service" id="router"/>
    <argument type="service" id="security.context"/>
    <argument type="service" id="event_dispatcher"/>
</service>

STEP 2)

Your EventListener itself

class LoginListener
{
    protected $router;
    protected $security;
    protected $dispatcher;

    public function __construct(Router $router, SecurityContext $security, EventDispatcher $dispatcher)
    {
        $this->router = $router;
        $this->security = $security;
        $this->dispatcher = $dispatcher;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
    }

    public function onKernelResponse(FilterResponseEvent $event)
    {
        if ($this->security->isGranted('ROLE_FACTORY')) 
        {
            $response = new RedirectResponse($this->router->generate('factory_homepage'));
        } 
        elseif ($this->security->isGranted('ROLE_CUSTOMER')) 
        {
            $response = new RedirectResponse($this->router->generate('customer_homepage'));
        } 
        else 
        {
            $response = new RedirectResponse($this->router->generate('default_homepage'));
        }

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

OPTION 2:

You can modify the vendor code at FOSUserBundle\Controller\SecurityController Add the following piece of code to make your loginAction look like this

public function loginAction(Request $request)
{
    $securityContext = $this->container->get('security.context');
    $router = $this->container->get('router');

    if ($securityContext->isGranted('ROLE_FACTORY')) 
    {
        return new RedirectResponse($router->generate('factory_homepage'));
    }
    elseif ($securityContext->isGranted('ROLE_CUSTOMER')) 
    {
        return new RedirectResponse($router->generate('customer_homepage'));
    }
    else
    {
        return new RedirectResponse($router->generate('default_homepage'));
    }
}