2012-04-25 37 views
14

Tengo una pregunta acerca de FOSUserBundle para Symfony 2.0.x. En su documentación, puede encontrar la manera de cambiar el inicio de sesión para que funcione con el nombre de usuario y el correo electrónico. Eso funciona genial! Pero quiero iniciar sesión para trabajar solo con el correo electrónico. Así que agregué una función en CustomUserManager (se extiende desde el original) que asegura que solo pueda iniciar sesión con su correo electrónico.FOSUserBundle iniciar sesión con correo electrónico (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; 

    } 
} 

Pero ahora tengo un problema que necesito para controlar los valores que se guardan en la sesión. Guarda mi nombre de usuario en la sesión y cuando el sistema lo comprueba no habrá ningún correo electrónico (porque solo revisa el correo electrónico) disponible.

Así que mi pregunta es cómo/dónde se puede cambiar el valor que se almacena dentro de la variable de nombre de usuario.

Gracias!

Respuesta

27

Esto puede hacerse reemplazando los emisores en la entidad Usuario:

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

    // ... 

} 

No es claro por su pregunta, pero a partir de los espacios de nombres que se supone que tiene su propio paquete niño que utiliza FOSUserBundle como su paquete de los padres (según FOSUserBundle documentation, ejemplo "b").

Si lo hace, puede anular fácilmente Formularios y plantillas para eliminar cualquier campo username de la interfaz de usuario y reemplazarlos por email campos. Dado que ha anulado los autores de correo electrónico como se indicó anteriormente, la propiedad username se completará correctamente.

Aunque esto funciona, no es una solución muy buena. La desventaja es que todavía tendrá columnas username y usernameCanonical en la base de datos. Originalmente queríamos eliminarlos por completo, pero esto requeriría demasiados cambios en FOSUserBundle (el atributo de nombre de usuario es requerido por \FOS\UserBundle\Model\UserInterface, y el código del paquete depende de él).

14

Encontré una solución realmente simple, tal vez no la mejor, ¡pero la simplicidad es poder! ;)

Estoy escribiendo aquí por si acaso es bueno para alguien.

puse la opción de nombre de usuario/correo electrónico de acceso de los proveedores:

en app/conf/security.yml:

providers: 
    fos_userbundle: 
     id: fos_user.user_provider.username_email 

Y luego, en la vista de la forma de la conexión dejo sólo para inicio de sesión con input type = "email":

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

Hola gracias por este NoFlag - esto funcionó perfectamente para mí. Lo estaba buscando en la referencia de configuración. Pero, como esto está realmente en la configuración de seguridad, no está en la [referencia de configuración de FOSUserBundle] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md). Para cualquier otra persona que hizo lo mismo que yo, debe buscarlo en [documentos de configuración de seguridad para FOSUserBundle] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/logging_by_username_or_email.md) – jfgrissom

+0

es tipo de entrada html5, para navegador reciente solamente –

+1

Si bien esto funciona y tendría sentido hacerlo de todos modos, tenga en cuenta que un usuario podría abrir herramientas dev y cambiar 'type =" email "' to 'type =" text "' y luego inicie sesión con un nombre de usuario.Obviamente, depende de su situación, ya sea que eso sea un problema o no. – bassplayer7

Cuestiones relacionadas