Symfony2, FOSUser, don't login user after rese

2019-04-14 08:02发布

I'm working on resetting password system with FosUser, and I don't know how can I remove the auto-login after user changes his password ?

Thanks for help, I don't want to override, I change directly FOS files.

4条回答
ら.Afraid
2楼-- · 2019-04-14 08:50

If you want to override the bundle, you will have to comment the line 132 in \vendor\friendsofsymfony\user-bundle\FOS\UserBundle\Controller\ResettingController.php :

$dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

which disable the auto-login. But as bartek says, it is not a good way to do that. Although it is only for one line... I hope it will help you, as I am concerned, I have comment a same line in the regitration by an overloading file on line :

$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

To disable the auto-login after the registration.

查看更多
Evening l夕情丶
3楼-- · 2019-04-14 08:59

Finally I think I found a light but clean way of doing this : events can be stopped ! check http://symfony.com/doc/current/components/event_dispatcher/introduction.html at Stopping Event Flow/Propagation. The event making login after registration seems to be REGISTRATION_COMPLETED, so make a subscriber to this event with a high priority

...
public static function getSubscribedEvents() {
    return array(
        FOSUserEvents::REGISTRATION_COMPLETED => ['onRegistrationCompleted',9999],
    );
}
public function onRegistrationCompleted(FilterUserResponseEvent $event) {
    // this trick prevent login now
    $event->stopPropagation();
}

Then if you fear that some important listener/subscribers loose the event, adjust the listen priority...

查看更多
再贱就再见
4楼-- · 2019-04-14 09:01

I also used a kind of similar solution as @David suggested. My requirement was that only Admin can create users and if user successfully created it should redirect to the list of the users page.

What I have done is that I have handled two/three event. The first one REGISTRATION_SUCCESS where I attached my custom redirect URL to the event as below (also mentioned in the doc):

 public static function getSubscribedEvents()
{
    return [
        FOSUserEvents::REGISTRATION_SUCCESS => [
            ['onRegistrationSuccess', -10],
        ],
    ];


}

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

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

And if you look at the code of FOSUserbundle RegistrationController after success two more events has been dispatching REGISTRATION_CONFIRM/ED. So I handled these events and have stopped them:

public static function getSubscribedEvents()
{
    return array(
        FOSUserEvents::REGISTRATION_COMPLETED => ['stopEvent', 9999],
        FOSUserEvents::REGISTRATION_CONFIRMED => ['stopEvent', 9999],

    );;


}

public function stopEvent(FilterUserResponseEvent $event) {

    $event->stopPropagation();
}

Hope this could help someone.

查看更多
走好不送
5楼-- · 2019-04-14 09:05

The proper way :)

Compiler Passes in Symfony allow you to manipulate other services. In this case you want to override fos_user.listener.authentication to use your custom subscriber instead of the one provided with FOSUserBundle FOS\UserBundle\EventListener\AuthenticationListener. You can just extends the provided one to subscribe only to the registration events and NOT to the resetting password event:

<?php
// src/YourCompany/YourBundle/EventListener/AuthenticationListener.php

namespace YourCompany\YourBundle\EventListener;

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\EventListener\AuthenticationListener as FOSAuthenticationListener;

class AuthenticationListener extends FOSAuthenticationListener
{

    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate',
            FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate'
        );
    }

}

To do so just define a Compiler Pass like this:

<?php
// src/YourCompany/YourBundle/DependencyInjection/Compiler/FOSUserOverridePass.php

namespace YourCompany\YourBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class FOSUserOverridePass implements CompilerPassInterface
{

    public function process(ContainerBuilder $container)
    {
        $container->getDefinition('fos_user.listener.authentication')->setClass('YourCompany\YourBundle\EventListener\AuthenticationListener');
    }

}

And then register your compiler pass in your bundle definition:

<?php
// src/YourCompany/YourBundle/YourCompanyYourBundle.php

namespace YourCompany\YourBundle;

use YourCompany\YourBundle\Compiler\FOSUserOverridePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class YourCompanyYourBundle extends Bundle
{

    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new FOSUserOverridePass());
    }

}

That's it!


Here's something to read: http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html

The service you are going to override: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/config/listeners.xml

And the original class: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/EventListener/AuthenticationListener.php

查看更多
登录 后发表回答