使用最新的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
为空。使用调试器,我可以验证我自己的侦听器事件是否被调用,但是也调用了原始事件。
答案 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));
}
}