Symfony2, FOSUser, don't login user after reset password

☆樱花仙子☆ 提交于 2019-12-06 10:03:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!