2012-04-25 1 views
14

Ho una domanda su FOSUserBundle per Symfony 2.0.x. In questa documentazione è possibile trovare il modo di modificare il login per lavorare con il nome utente e l'e-mail. Funziona alla grande! Ma voglio accedere per lavorare con solo l'email. Così ho aggiunto una funzione nel mio CustomUserManager (si estende dall'originale) che ti assicura che puoi semplicemente accedere con la tua email.Login FOSUserBundle con e-mail (Symfony2)

namespace Frontend\UserBundle\Model; 

use FOS\UserBundle\Entity\UserManager; 
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 

class CustomUserManager extends UserManager 
{ 
    public function loadUserByUsername($email) 
    { 
     /*$user = $this->findUserByUsernameOrEmail($username); 

     if (!$user) { 
      throw new UsernameNotFoundException(sprintf('No user with name "%s" was found.', $username)); 
     } 

     return $user;*/ 

     //Change it to only email (Default calls loadUserByUsername -> we send it to our own loadUserByEmail) 
     return $this->loadUserByEmail($email); 
    } 

    public function loadUserByEmail($email) 
    { 
     $user = $this->findUserByEmail($email); 

     if (!$user) { 
      throw new UsernameNotFoundException(sprintf('No user with email "%s" was found.', $email)); 
     } 

     return $user; 

    } 
} 

Ma ora ho un problema che ho bisogno di controllare i valori che vengono salvati nella sessione. Salva il mio nome utente nella sessione e quando il sistema verifica che non ci sarà nessuna email (perché controlla solo l'email) disponibile.

Quindi la mia domanda è come/dove è possibile modificare il valore che è memorizzato all'interno della variabile username.

Grazie!

risposta

27

Questo può essere fatto mediante l'override setter nell'entità Utente:

<?php 

namespace Acme\UserBundle\Entity; 

use FOS\UserBundle\Entity\User as BaseUser; 
use Doctrine\ORM\Mapping as ORM; 
use Gedmo\Mapping\Annotation as Gedmo; 

/** 
* @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\UserRepository") 
* @ORM\Table(name="users") 
*/ 
class User extends BaseUser 
{ 

    // ... 

    // override methods for username and tie them with email field 

    /** 
    * Sets the email. 
    * 
    * @param string $email 
    * @return User 
    */ 
    public function setEmail($email) 
    { 
     $this->setUsername($email); 

     return parent::setEmail($email); 
    } 

    /** 
    * Set the canonical email. 
    * 
    * @param string $emailCanonical 
    * @return User 
    */ 
    public function setEmailCanonical($emailCanonical) 
    { 
     $this->setUsernameCanonical($emailCanonical); 

     return parent::setEmailCanonical($emailCanonical); 
    } 

    // ... 

} 

Non è chiaro dalla tua domanda, ma dai vostri spazi dei nomi suppongo che avete il vostro pacco bambino che utilizza FOSUserBundle come il suo fascio genitore (come da FOSUserBundle documentation, esempio "b").

Se lo si fa, è possibile sovrascrivere facilmente moduli e modelli per rimuovere i campi username dall'interfaccia utente e sostituirli con i campi email. Poiché hai sovrascritto i setter email come sopra, la proprietà username verrà popolata correttamente.

Anche se funziona, non è una soluzione molto bella. Lo svantaggio è che avrai ancora username e usernameCanonical colonne nel database. Inizialmente volevamo rimuoverli completamente, ma ciò richiederebbe troppe modifiche in FOSUserBundle (l'attributo username è richiesto da \FOS\UserBundle\Model\UserInterface e il codice bundle dipende da questo).

14

Ho trovato una soluzione davvero semplice, forse non la migliore ma la semplicità è potere! ;)

Sto scrivendo qui solo nel caso sia un bene per qualcuno.

ho messo l'opzione/email di accesso nome utente nel fornitori:

in app/conf/security.yml:

providers: 
    fos_userbundle: 
     id: fos_user.user_provider.username_email 

E poi nella visualizzazione del modulo di login ho lasciato solo per il login con input type = "email":

<input type="email" class="form-control" id="username" placeholder="E-Mail" name="_username" required="required"/> 
+0

Hey grazie per questo noflag - questo ha funzionato perfettamente per me è stato. Lo stavo cercando nel riferimento di configurazione. Ma, poiché questo è in realtà nella configurazione di sicurezza, non è nel riferimento di configurazione [FOSUserBundle] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md). Per chiunque altro ha fatto la stessa cosa che ho fatto - Devi cercarlo nei [documenti di configurazione sicurezza per FOSUserBundle] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/logging_by_username_or_email.md). – jfgrissom

+0

è tipo di input html5, solo per browser recenti –

+1

Sebbene funzioni e abbia senso fare comunque, tenere presente che un utente potrebbe aprire gli strumenti di sviluppo e modificare 'type =" email "' a 'type =" text "' e quindi accedi con un nome utente.Dipende ovviamente dalla tua situazione se questo sarebbe un problema o no. – bassplayer7