2016-01-21 21 views
5

Utilizzando l'ultimo Symfony e FOSUserbundle, dopo aver registrato con successo un nuovo utente, l'utente si collega automaticamente. Voglio impedirlo. La mia ragione è che solo un utente speciale dovrebbe essere in grado di registrare nuovi utenti.Disabilita l'accesso automatico dopo la registrazione in FOSUserbundle di Symfony

Suppongo di dover eseguire l'override del registroAzione nel RegisterController del pacchetto, ma non so come.

Ho provato: http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html, ma sembra essere obsoleto, nessun utente è stato creato con questo metodo.

Eventuali suggerimenti sono apprezzati.

Edit:

ho scoperto che non ho creato correttamente il fascio bambino. Ho anche dovuto creare il mio EventListener. Funziona ora quando sovrascrivo l'evento FOSUserEvents::REGISTRATION_SUCCESS.

cosa strana è che quando uso l'evento FOSUserEvents::REGISTRATION_COMPLETED, entrambi gli eventi vengono inviati, il mio fagotto e il FOSUserbundle di, in modo tale che l'utente viene reindirizzato al sito corretto, ma il login come nuovo utente.

Edit 2:

Quindi questo è nel mio ascoltatore:

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

} 

ho impostato il reindirizzamento in caso REGISTRATION_SUCCESS e il REGISTRATION_COMPLETED è vuoto. Con il debugger posso verificare che venga chiamato l'evento del mio ascoltatore, ma viene chiamato anche l'evento originale.

+1

documenti mi sembrano ok. Esistono diversi modi per sovrascrivere un file di bundle. Stai facendo un "figlio" di userbundle come nei documenti? o qualcosa di diverso? Inoltre, se sei alla ricerca di un amministratore solo per poter creare utenti, forse il lato registro di FOSuserBundle è il bit sbagliato? Sicuramente la creazione di un CRUD per gestire gli utenti dietro un firewall amministratore sarebbe meglio? – DevDonkey

+0

@DevDonkey: avevi ragione, non sono riuscito a creare il pacchetto correttamente. Sembra funzionare ora. Forse creare un CRUD sarebbe stato più facile. – dev0

+0

cool, felice che tu abbia risolto il problema. – DevDonkey

risposta

0

È possibile risolvere questo problema con un listener, in bundle utente fos, autentica l'utente dopo la registrazione.

di file: friendsofsymfony/user-bundle/EventListener/AuthenticationListener.php

classe: FOS\UserBundle\EventListener\AuthenticationListener

Se si seleziona questa classe si dovrebbe vedere rintraccia REGISTRATION_COMPLETED evento.

In Authenticatiton Listener Invia evento dopo l'attivazione della funzione logInUser. Pertanto è necessario disconnettere l'utente nel listener che sottoscrive 'REGISTRAZIONE COMPLETATA.

è possibile controllare https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/controller_events.rst per scrivere il listener all'utente di disconnessione.

Nota: Potrebbe non essere un buon log-in log-out utente in ogni processo di registrazione, ma se si utilizza fosuserbundle il modo più semplice e il footprint minimo sarebbe questo, se esiste già una configurazione yml non esiste , in realtà nel codice non c'è la direzione di yml conf. Quindi questo approccio sarebbe min. orma.

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

Non voglio che l'utente effettui il login in primo luogo. Ecco perché sovrascrivo l'evento 'REGISTRATION_COMPLETED' dove il nuovo utente è autenticato per impostazione predefinita. – dev0

+0

Intendi dire che hai esteso il pacchetto quando dici di ignorare l'evento? – FZE

+0

Ooops Ho appena imparato la tecnica per sovrascrivere un servizio/listener per service.yml thats cool stuff :) http://stackoverflow.com/questions/18745087/how-to-override-fosuserbundles-emailconfirmationlistener – FZE

0

siete quasi arrivati, come ha detto lei vostri ascoltatori sono chiamati, ma l'ordine non è corretto, quindi è necessario per rendere il vostro ascoltatore essere eseguito prima di quello di default Per fare questo cambiamento

FOSUserEvents :: REGISTRATION_SUCCESS => 'onRegistrationSuccess'

a

FOSUserEvents :: REGISTRATION_SUCCESS => [ 'onRegistrationSuccess', - 10],

notare la -10 là, questo cambia la priorità di chi ascolta.

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

} 




} 

Sto usando symfony 2.8 con la versione FOSBundle

friendsofsymfony/user-fascio dev-master 1f97ccf Symfony FOSUserBundle

secondo l'uscita di composer info

+0

Grazie per la risposta , sfortunatamente non posso testarlo ora poiché il progetto è già stato completato. – dev0

0

EDIT: Questa tecnica funziona su Symfony 3.3, non so se questo wo rks su versioni inferiori.

Il modo corretto di farlo è creando un Compiler Pass.

È anche possibile: eseguire l'override del servizio aggiungendo un nuovo servizio con lo stesso nome: fos_user.listener.authentication sul proprio file app/config.yml o sul file di configurazione del bundle e aggiungendo la nuova classe ad esso come I ' ve fatto sotto e aggiungere questo

Ecco come sovrascrivere la registrazione automatica quando si registra un nuovo utente utilizzando la tecnica del passaggio del compilatore.

il compilatore Passo

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

} 

l'override Servizio

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

Pubblica il tuo pass compilatore sul vostro file fascio principale

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

    } 

} 

Esistono altri modi, come sovrascrivere il servizio di autenticazione su config.yml, ma la soluzione di cui sopra è la soluzione più pulita e più manutenibile che ho trovato.

Problemi correlati