在Symfony的FOSUserbundle中注册后禁用自动登录

时间:2016-01-21 14:35:19

标签: php symfony fosuserbundle

使用最新的Symfony和FOSUserbundle,在成功注册新用户后,用户将自动登录。我想阻止这种情况。我的理由是只有特殊用户才能注册新用户。

我想我必须覆盖捆绑包的RegisterController中的registerAction,但我不知道如何。

我尝试过:http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html,但似乎已过时,没有使用此方法创建用户。

任何提示都表示赞赏。

修改

我发现我没有正确创建子包。我还必须创建自己的EventListener。当我覆盖FOSUserEvents::REGISTRATION_SUCCESS事件时,它现在可以正常工作。

奇怪的是,当我使用FOSUserEvents::REGISTRATION_COMPLETED事件时,会调度这两个事件,我的捆绑包和FOSUserbundle,以便用户被重定向到正确的站点,但是已记录作为新用户。

编辑2:

所以这是我的听众:

public static function getSubscribedEvents()
{
    return array(
        FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
        FOSUserEvents::REGISTRATION_COMPLETED => 'onRegistrationCompleted',
    );
}

public function onRegistrationSuccess(FormEvent  $event)
{
    $url = $this->router->generate('admin');

    $event->setResponse(new RedirectResponse($url));
}

public function onRegistrationCompleted(FilterUserResponseEvent  $event)
{

}

我在REGISTRATION_SUCCESS事件中设置了重定向,REGISTRATION_COMPLETED为空。使用调试器,我可以验证我自己的侦听器事件是否被调用,但是也调用了原始事件。

4 个答案:

答案 0 :(得分:1)

您可以使用监听器解决此问题,在fos用户捆绑包中,它会在注册后对用户进行身份验证。

档案:friendsofsymfony/user-bundle/EventListener/AuthenticationListener.php

课程:FOS\UserBundle\EventListener\AuthenticationListener

如果您查看此课程,则会看到它跟踪REGISTRATION_COMPLETED事件。

Authenticatiton Listener中,在触发logInUser功能后调度事件。因此,您必须在您的监听器中注销用户,该用户订阅了“REGISTRATION COMPLETED。”

您可以检查https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/controller_events.rst是否要将您的监听器写入注销用户。

注意:在每个注册过程中登录注销用户可能不是一个好方法,但是如果你使用fosuserbundle最简单的方法,那么最小的占用空间就是这个,如果已经有一个yml配置不存在,实际上在代码中没有yml conf的方向。所以这种方法将是最小的。足迹。

    try {
        $this->loginManager->logInUser($this->firewallName, $event->getUser(), $event->getResponse());

        $eventDispatcher->dispatch(FOSUserEvents::SECURITY_IMPLICIT_LOGIN, new UserEvent($event->getUser(), $event->getRequest()));
    } catch (AccountStatusException $ex) {
        // We simply do not authenticate users which do not pass the user
        // checker (not enabled, expired, etc.).
    }

答案 1 :(得分:1)

编辑:这项技术适用于Symfony 3.3,我不知道这是否适用于较低版本。

正确的方法是创建Compiler Pass

您还可以:通过在app / config.yml文件或捆绑配置文件中添加使用相同名称的新服务来覆盖服务:fos_user.listener.authentication,并将我的新类添加到其中在下面完成并添加此

以下是使用编译器传递技术注册新用户时如何覆盖自动记录。

编译器通行证

namespace arpa3\UserBundle\DependencyInjection;

use arpa3\UserBundle\EventListener\AuthenticationListener;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;


class OverrideServiceCompilerPass implements CompilerPassInterface {

    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('fos_user.listener.authentication');
        $definition->setClass(AuthenticationListener::class);
    }

}

服务覆盖

namespace arpa3\UserBundle\EventListener;

use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Security\LoginManagerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Exception\AccountStatusException;

class AuthenticationListener implements EventSubscriberInterface
{
    /**
     * @var LoginManagerInterface
     */
    private $loginManager;

    /**
     * @var string
     */
    private $firewallName;

    /**
     * AuthenticationListener constructor.
     *
     * @param LoginManagerInterface $loginManager
     * @param string                $firewallName
     */
    public function __construct(LoginManagerInterface $loginManager, $firewallName)
    {
        $this->loginManager = $loginManager;
        $this->firewallName = $firewallName;
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
           // You can disable any of them or all of them as you want
           //FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate',
           //FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate',
           //FOSUserEvents::RESETTING_RESET_COMPLETED => 'authenticate',
        );
    }

    /**
     * @param FilterUserResponseEvent  $event
     * @param string                   $eventName
     * @param EventDispatcherInterface $eventDispatcher
     */
    public function authenticate(FilterUserResponseEvent $event, $eventName, EventDispatcherInterface $eventDispatcher)
    {
        try {
            $this->loginManager->logInUser($this->firewallName, $event->getUser(), $event->getResponse());

            $eventDispatcher->dispatch(FOSUserEvents::SECURITY_IMPLICIT_LOGIN, new UserEvent($event->getUser(), $event->getRequest()));
        } catch (AccountStatusException $ex) {
            // We simply do not authenticate users which do not pass the user
            // checker (not enabled, expired, etc.).
        }
    }
}

在主要包文件上注册编译器通行证

    namespace arpa3\UserBundle;

use arpa3\UserBundle\DependencyInjection\OverrideServiceCompilerPass;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class arpa3UserBundle extends Bundle {

    public function getParent () {

        return 'FOSUserBundle';
    }

    /**
     *
     * This injects a Compiler Pass that is used to override the automatic login after registration of a new user
     * We have done this in order to disable the "by default" behaviour given that only admins can register users
     * and logging in into the newly created account automatically is just not a desired behaviour
     *
     * @param ContainerBuilder $container
     */
    public function build ( ContainerBuilder $container ) {

        parent ::build( $container );

        $container -> addCompilerPass( new OverrideServiceCompilerPass() );

    }

}

还有其他方法可以覆盖config.yml上的身份验证服务,但上面的解决方案是我找到的最干净,最易维护的解决方案。

答案 2 :(得分:1)

实际上,不需要执行任何这些操作。如果fos_user.listener.authentication设置为false,则会从容器中删除use_authentication_listener服务。

请参见FOS\UserBundle\DependencyInjection\FOSUserExtension中的line 74-76

此信息也包含在文档FOS UserBundle Configuration中。

答案 3 :(得分:0)

你几乎就在那里,因为你说你的听众被叫,但是顺序不正确,所以你需要让你的听众在默认之前被执行 为了做那个改变

  

FOSUserEvents :: REGISTRATION_SUCCESS =>   ' onRegistrationSuccess'

  

FOSUserEvents :: REGISTRATION_SUCCESS =>   [' onRegistrationSuccess', - 10]

注意 -10 ,这会改变侦听器的优先级。

@EnableJpaRepositories

我正在使用带有FOSBundle版本的symfony 2.8

  

friendsofsymfony / user-bundle dev-master 1f97ccf Symfony FOSUserBundle

根据class RegistrationSuccessEventListener implements EventSubscriberInterface{ private $router; public function __construct(UrlGeneratorInterface $router){ $this->router = $router; } public static function getSubscribedEvents() { //this will be called before return array( FOSUserEvents::REGISTRATION_SUCCESS => ['onUserRegistrationSuccess', -30], ); } /** * @param FormEvent $event * When the user registration is completed redirect * to the employee list page and avoid the automatic * mail sending and user authentication that happends * */ public function onUserRegistrationSuccess(FormEvent $event){ $url = $this->router->generate('employees_list'); $event->setResponse(new RedirectResponse($url)); } }

的输出
相关问题