2016-02-02 35 views
5

Stavo cercando di creare un fornitore di servizi per accedere con e-mail e non con FOSUserBundle.Accesso FOSUsBundle con e-mail con provider di servizi, best practice

Per prima cosa ho scritto questo nel mio file security.yml secondo il doc here:

security: 
    providers: 
     fos_userbundle: 
      id: fos_user.user_provider.username_email 

Secondo il FOS doc, seguo questi steps uno per uno.

Salvo MyUserManager.php ho scritto questo (secondo un'altra domanda sulla pila here):

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; 

    } 
} 

e, naturalmente, ho cambiato la classe utente al fine di attuare getter e setter specifico come questo:

namespace Acme\UserBundle\Entity; 

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

/** 
* @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); 
    } 

    // ... 

} 

Ma io owerride forma modello FOSUser in app\Resources\FOSUserBundle\views\Security\login.html.twig come questo:

{% block fos_user_content %} 
    <form action="{{ path("fos_user_security_check") }}" method="post"> 

    <input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/> 

    <label class="" for="username">E-mail</label> 
    <input type="email" class="" id="username" name="_username" required="required"/> 

    <label class="" for="password">{{ 'security.login.password'|trans }}</label> 
    <input class="" type="password" id="password" name="_password" required="required"/> 

    <label class="" for="remember_me"> 
     <input type="checkbox" id="remember_me" name="_remember_me" class=""> 
     <span class="">{{ 'security.login.remember_me'|trans }}</span> 
    </label> 

    <button class="" type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}"> 
     LogIn 
    </button> 
    </form> 
{% endblock fos_user_content %} 

È il buon modo di consentire l'accesso utente solo con campo di posta elettronica e non il nome utente?

+2

Sì, è possibile utilizzare in questo modo. Sto lavorando così ed è ok. –

+0

@ MertÖKSÜZ grazie per la risposta, se va bene spero che possa aiutare altri amanti di symfony! –

+0

lo spero anch'io :) grazie. –

risposta

4

L'approccio riprende perfettamente tutte le modifiche obbligatorie per l'impostazione di un'autenticazione della password e-mail su FOSUserBundle.

Per ora, ho utilizzato solo la stessa configurazione in configurazione di sicurezza e di entità (non è necessario il modello perché il mio login è fatto in AJAX). L'unico dubbio che ho è il seguente:

Come il username è sempre impostato utilizzando il valore email campo, è utile per creare il tuo CustomUserManager?
Il nome utente loadByU funziona se il nome utente è sempre uguale all'e-mail, come fatto dall'entità in setEmail e setEmailCanonical.

È solo una sicurezza aggiuntiva?

EDIT

Passaggio da nome utente per e-mail può comporta cambiare alcune comportment in forma dell'edificio/validazione.

Forse si deve guardare a questa risposta: https://stackoverflow.com/a/21064627/4363634

+1

come ho potuto leggere su Symfony doc, il processo di autenticazione dipende da 'provider utenti '. Quando un utente invia un messaggio e-mail e una password, il livello di autenticazione chiede al provider utente configurato di restituire un oggetto utente per un determinato argomento (qui email). Quindi devo inserire UserManger per rimanere in forma con il documento. Sto solo seguendo il documento per essere sicuro che sia la migliore pratica. Spero tu capisca cosa mi piacerebbe fare e potrebbe aiutarti se ne hai bisogno. –

+1

Ok ora è chiaro per me, ho molto da imparare e leggere la documentazione su come viene gestita la sicurezza in Symfony. Cercherò su questo e sicuramente applicherò la tua logica per il prossimo per garantire un massimo di casi d'uso. Grazie per la tua risposta. – chalasr

+0

prego. Inserisco questa domanda qui per assicurarmi di aver creato il giusto metodo/pratica e di avere qualche suggerimento sugli altri sviluppatori se non lo è. Sono felice se questo potrebbe aiutarti. –