问题
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.
回答1:
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
回答2:
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.
回答3:
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:
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.
来源:https://stackoverflow.com/questions/23956845/symfony2-fosuser-dont-login-user-after-reset-password