2013-01-10 13 views
5

Ho cercato di creare un modulo di accesso oggi utilizzando Symfony2 in cui un utente può accedere utilizzando il proprio indirizzo e-mail e la password. Ho avuto molti problemi e alla fine ho capito che funzionerà solo se avrò una proprietà $username nella mia classe di entità . Ho provato a utilizzare la posta elettronica anziché il nome utente, laddove possibile, quindi qualcuno può spiegare perché è richiesto $username o dove ho sbagliato? Inoltre, nel mio file login.html.twig sto ancora usando _username anziché _email se questo fa qualche differenza? Il mio codice è al di sotto (ho rimosso alcuni getter e setter che non sono applicabili):Symfony2 autenticazione/accesso tramite e-mail anziché nome utente

AdminUser entità:

namespace XXX\WebsiteBundle\Entity; 

use Symfony\Component\Security\Core\User\UserInterface; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* AdminUser 
* 
* @ORM\Table(name="admin_user",indexes={@ORM\Index(name="indexes", columns={"deleted"})}) 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks() 
*/ 
class AdminUser implements UserInterface 
{ 
/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="name", type="string", length=45) 
*/ 
private $name; 

/** 
* @var string 
* 
* @ORM\Column(name="email", type="string", length=45, unique=true) 
*/ 
private $email; 

/** 
* @var string 
* 
* @ORM\Column(name="salt", type="string", length=255) 
*/ 
private $salt; 

/** 
* @var string 
* 
* @ORM\Column(name="password", type="string", length=255) 
*/ 
private $password; 

/** 
* @var integer 
* 
* @ORM\Column(name="enabled", type="integer", options={"default" = 0}) 
*/ 
private $enabled; 

/** 
* @var string[] $roles 
* 
* @ORM\Column(name="roles", type="array") 
*/ 
private $roles = array(); 

private $username; 


/** 
* Gets the username. 
* 
* @return string The username. 
*/ 
public function getUsername() 
{ 
    return $this->email; 
} 

/** 
* Erases the user credentials. 
*/ 
public function eraseCredentials() 
{ 

} 


/** 
* Returns the roles granted to the user. 
* 
* <code> 
* public function getRoles() 
* { 
*  return array('ROLE_USER'); 
* } 
* </code> 
* 
* Alternatively, the roles might be stored on a ``roles`` property, 
* and populated in any number of different ways when the user object 
* is created. 
* 
* @return Role[] The user roles 
*/ 
public function getRoles() { 
    return $this -> roles; 
} 

/** 
* Set the roles of the user 
* 
* @var string[] $roles 
* 
* @return \XXX\WebsiteBundle\Entity\User this 
*/ 
public function setRoles(array $roles) { 
    $this -> roles = $roles; 

    return $this; 
} 



} 

Il mio file security.yml è:

jms_security_extra: secure_all_services: false espressioni: true

security: 
encoders: 
    XXX\WebsiteBundle\Entity\AdminUser: sha512 

role_hierarchy: 
    ROLE_ADMIN:  ROLE_USER 
    ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] 

providers: 
    main_provider: 
     entity: { class: XXX\WebsiteBundle\Entity\AdminUser, property: email } 

firewalls: 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 

    admin_firewall: 
     pattern: ^/admin.* 
     anonymous: ~ 
     form_login: 
      login_path: /admin/login 
      check_path: /admin/login_check 

access_control: 
    - { path: ^/admin/login.*, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
    - { path: ^/admin.*, roles: ROLE_ADMIN } 
+0

È necessario avere un metodo getUsername() in AdminUser solo per soddisfare i requisiti dell'interfaccia utente. Ma può restituire email come se ce l'avessi. La proprietà: l'e-mail dovrebbe essere tutto ciò che devi fare. Puoi guardare nella classe EntityUserProvider solo per verificare cosa sta succedendo. Magari iniziare con una nuova installazione? A volte rovino le cose mentre risolvo i problemi. – Cerad

risposta

0

Questo è kinda hacker, ma è possibile rimuovere il campo nome utente dai vostri moduli di registrazione, e nella tua entità utente, fare questo:

public function setEmail($email) 
{ 
    $this->email = $email; 
    $this->username = $email; 
} 
+1

Sì, suppongo, tuttavia sto cercando di imparare le migliori pratiche e prevenire molti attacchi. Ho trovato questa pagina - http://symfony.com/doc/current/cookbook/security/entity_provider.html#authenticating-someone-with-a-custom-entity-provider dovrei creare un AdminUserRepository? – user1961082

8

Credo che si dovrebbe modificare la proprietà con la posta elettronica e inoltre è possibile cambiare il parametro _username con tutto quello che vuoi da:

entity: 
      entity: 
       class:    SecurityBundle:User 
       property:   username 

e

firewalls 
    form_login: 
     username_parameter: _username 

può essere si dovrebbe avere uno sguardo a security configuration document

+1

funziona per me, l'unico "pezzo" rimasto è il metodo getUsername() dovuto all'interfaccia UserInterface. – Cesar

+1

funziona sotto securty.yml -> firewall -> main -> form_login: -> username_parameter: email e of course nome input = 'email' –

+0

maggiori informazioni http://symfony.com/doc/2.3/reference/configuration/security .html –

0

Provare e utilizzare FOSUserBundle.

Ha un valore predefinito feature per consentire agli utenti di accedere con il proprio nome utente o campi di posta elettronica.

+3

FOSUserBundle non consente l'accesso solo tramite posta elettronica. Permette solo il nome utente e se il nome utente o l'e-mail sono configurati. Ho solo pensato di chiarirlo a quelli che cercano una risposta a questa domanda. – Twifty

+0

Se la domanda riguardava i diversi modi di implementare l'autenticazione dell'utente, questa sarebbe una risposta valida. Ma il problema dell'utente non è correlato al pacchetto menzionato. –

1
firewalls: 
main: 
    form_login: 
    username_parameter: _email 

Tutto il codice è corretto, è sufficiente apportare alcune modifiche al file security.yml. aggiungi semplicemente username_parameter.

Problemi correlati