2013-01-10 11 views
5

Próbowałem już dzisiaj utworzyć formularz logowania za pomocą Symfony2, gdzie użytkownik może się logować przy użyciu swojego adresu e-mail i hasła. Miałem wiele problemów i ostatecznie zdałem sobie sprawę, że zadziała tylko wtedy, gdy posiadam właściwość $username w klasie encji AdminUser. Próbowałem używać adresu e-mail zamiast nazwy użytkownika, jeśli to możliwe, więc czy ktoś może wyjaśnić, dlaczego jest on wymagany lub gdzie się zepsułem? Ponadto w moim pliku login.html.twig nadal używam _username, a nie _email, jeśli to robi jakąkolwiek różnicę? Moje kodu jest poniżej (I zostały usunięte niektóre pobierające i ustawiające, które nie mają zastosowanie):Uwierzytelnianie Symfony2/logowanie przy użyciu adresu e-mail zamiast nazwy użytkownika

AdminUser jednostki:

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



} 

mój plik security.yml jest:

jms_security_extra: secure_all_services: false wyrażeń: 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

Musisz mieć metodę getUsername() w AdminUser, aby spełnić wymagania interfejsu użytkownika. Ale może zwrócić e-mail, jak to masz. Właściwość: e-mail powinien być wszystkim, co musisz zrobić. Możesz zajrzeć do klasy EntityUserProvider, aby sprawdzić, co się dzieje. Może zacznij od nowej instalacji? Czasami mylę się podczas rozwiązywania problemów. – Cerad

Odpowiedz

0

To trochę hackish, ale można usunąć pole nazwę użytkownika z formularzy rejestracyjnych, aw swojej jednostce użytkownika, wykonaj następujące czynności:

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

Tak, przypuszczam, ale staram się poznać najlepsze praktyki i zapobiec hakerstwu. Znalazłem tę stronę - http://symfony.com/doc/current/cookbook/security/entity_provider.html#authenticating-someone-with-a-custom-entity-provider musiałbym utworzyć AdminUserRepository? – user1961082

8

Chyba należy zmienić właściwość z poczty elektronicznej, a także można zmienić _username parametr z czymkolwiek chcesz przez:

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

i

firewalls 
    form_login: 
     username_parameter: _username 

może trzeba spojrzeć na security configuration document

+1

działa dla mnie, jedyny "kawałek" pozostawił jego metodę getUsername() z powodu interfejsu UserInterface. – Cesar

+1

działa pod securty.yml -> zapory ogniowe -> główne -> form_login: -> nazwa_użytkownika_parametr: e-mail i corse input name = 'email' –

+0

więcej informacji http://symfony.com/doc/2.3/reference/configuration/security .html –

0

Wypróbuj i użyj FOSUserBundle.

Ma domyślne feature, aby użytkownicy mogli logować się przy użyciu swojej nazwy użytkownika lub pól poczty e-mail.

+3

FOSUserBundle nie zezwala na logowanie tylko przez e-mail. Umożliwia tylko nazwę użytkownika i skonfigurowaną nazwę użytkownika lub adres e-mail. Pomyślałem, że wyjaśnię to tym, którzy szukają odpowiedzi na to pytanie. – Twifty

+0

Jeśli pytanie dotyczyło różnych sposobów implementacji uwierzytelniania użytkownika, byłaby to poprawna odpowiedź. Ale problem użytkownika nie jest związany z wymienionym pakietem. –

1
firewalls: 
main: 
    form_login: 
    username_parameter: _email 

Cały kod jest poprawny, wystarczy dokonać niewielkiej zmiany w pliku security.yml. po prostu dodaj parametr nazwa_użytkownika_parametru.

Powiązane problemy