Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在Symfony'中注册后禁用自动登录;福苏斯邦德酒店_Php_Symfony_Fosuserbundle - Fatal编程技术网

Php 在Symfony'中注册后禁用自动登录;福苏斯邦德酒店

Php 在Symfony'中注册后禁用自动登录;福苏斯邦德酒店,php,symfony,fosuserbundle,Php,Symfony,Fosuserbundle,使用最新的Symfony和FOSUserbundle,成功注册新用户后,用户将自动登录。我想阻止这一切。我的理由是,只有特殊用户才能注册新用户 我想我必须重写捆绑包的RegisterController中的registerAction,但我不知道如何重写 我尝试了:,但它似乎已经过时,没有使用此方法创建用户 如有任何提示,我们将不胜感激 编辑: 我发现我没有正确创建子捆绑包。我还必须创建自己的EventListener。现在,当我覆盖FOSUserEvents::REGISTRATION\u S

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

我想我必须重写捆绑包的RegisterController中的registerAction,但我不知道如何重写

我尝试了:,但它似乎已经过时,没有使用此方法创建用户

如有任何提示,我们将不胜感激

编辑:

我发现我没有正确创建子捆绑包。我还必须创建自己的EventListener。现在,当我覆盖
FOSUserEvents::REGISTRATION\u SUCCESS
事件时,它就可以工作了

奇怪的是,当我使用
FOSUserEvents::REGISTRATION\u COMPLETED
事件时,我的bundle和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\u SUCCESS
事件中设置重定向,并且
REGISTRATION\u COMPLETED
为空。使用调试器,我可以验证是否调用了我自己的侦听器事件,但也调用了原始事件

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

文件:
friendsofsymfony/user bundle/EventListener/AuthenticationListener.php

类:
FOS\UserBundle\EventListener\AuthenticationListener

如果您选中该类,您将看到它跟踪
注册\u完成的事件

authenticationlistener
中,它在触发
logInUser
函数后发送事件。因此,您必须注销监听器中的用户,该用户订阅“注册已完成”

您可以检查是否将侦听器写入注销用户

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

    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.).
    }

您就快到了,正如您所说,您的侦听器已被调用,但顺序不正确,因此您需要使您的侦听器在默认侦听器之前执行 为了实现这一改变

FOSUserEvents::注册成功=> “onRegistrationSuccess”

FOSUserEvents::注册成功=> ['onRegistrationSuccess',-10]

注意这里的-10,这会更改侦听器的优先级

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));

}




}
我在FOSBundle版本中使用symfony 2.8

friendsofsymfony/用户捆绑开发主机1f97ccf Symfony FOSUserBundle


根据
composer info

EDIT:的输出,这项技术适用于Symfony 3.3,我不知道它是否适用于较低版本

正确的方法是创建一个

您还可以:通过在app/config.yml文件或bundle config文件上添加一个名称相同的新服务来覆盖该服务: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() );

    }

}
在主捆绑文件上注册编译器密码

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上的身份验证服务,但上面的解决方案是我找到的最干净、最可维护的解决方案。

实际上,不需要做任何这些。如果
use\u authentication\u listener
设置为false,则从容器中删除
fos\u user.listener.authentication
服务

请参见
FOS\UserBundle\DependencyInjection\FOSUserExtension


此信息也包含在文档中。

文档看起来不错。有许多方法可以覆盖bundles文件。您是否正在制作文档中的userbundle的“子”文件?还是别的什么?另外,如果您在管理员之后只能创建用户,那么可能FOSuserBundle的注册端是错误的位?当然,在管理员防火墙后面创建一个CRUD来管理用户会更好吗?@DevDonkey:你是对的,我没有正确创建捆绑包。现在好像有用了。也许创建一个CRUD会更容易。酷,很高兴你把它整理好了。我不希望用户首先登录。这就是为什么我会覆盖新用户在默认情况下通过身份验证的
REGISTRATION\u COMPLETED
事件。你是说你说覆盖事件时扩展了捆绑包吗?哦,我刚刚学会了通过服务覆盖服务/侦听器的技术。yml这很酷:)谢谢你的回答,不幸的是,我现在无法测试它,因为项目已经完成。