2016-02-02 12 views
5

Szukałem utworzenia dostawcy usług w celu zalogowania się za pomocą poczty e-mail, a nie nazwy użytkownika za pomocą FOSUserBundle.Logowanie do FOSUserBundle za pomocą poczty e-mail z dostawcą usług, najlepsza praktyka

Najpierw napisałem to w moim pliku security.yml według doc here:

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

Według FOS doc, śledzę te steps jeden po drugim.

wyjątkiem MyUserManager.php Napisałem to (zgodnie z innym pytaniem na stosie 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; 

    } 
} 

i oczywiście zmieniłem klasę użytkownika w celu wykonania konkretnego getter i setter tak:

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

    // ... 

} 

Ale owerride formularz szablonu FOSUser w app\Resources\FOSUserBundle\views\Security\login.html.twig tak:

{% 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 %} 

Jest to dobry sposób, aby zezwolić użytkownikowi tylko na zalogowanie się w polu adresu e-mail, a nie na nazwę użytkownika?

+2

Tak, można użyć takiego. Pracuję w ten sposób i jest w porządku. –

+0

@ MertÖKSÜZ dziękuję za odpowiedź, jeśli jest dobra, mam nadzieję, że mogłaby pomóc innym miłośnikom symfonii! –

+0

też mam nadzieję :) dziękuję. –

Odpowiedz

4

Twoje podejście obejmuje idealnie wszystkie obowiązkowe zmiany w celu skonfigurowania uwierzytelniania za pomocą hasła w usłudze FOSUserBundle.

Na razie użyłem tylko tej samej konfiguracji w encji i konfiguracji zabezpieczeń (nie trzeba szablonu, ponieważ mój login jest wykonywany w AJAX). Jedyne wątpliwości mam jest następujący:

Jako username odbywa się za pomocą wartości email pola, jest ona przydatna do tworzenia CustomUserManager?
Nazwa loadByUsername będzie działać, jeśli nazwa użytkownika jest zawsze równa adresowi e-mail, tak jak zrobiła to Twoja jednostka w setEmail i setEmailCanonical.

Czy to tylko dodatkowe zabezpieczenie?

EDIT

Zmiana od użytkownika lub e-mail może wiąże się zmienić trochę comportment w postaci budynku/walidacji.

Może trzeba spojrzeć na to odpowiedź: https://stackoverflow.com/a/21064627/4363634

+1

jak mogłem przeczytać w dokumencie Symfony proces uwierzytelniania zależy od "dostarczycieli użytkownika". Gdy użytkownik wysyła wiadomość e-mail i hasło, warstwa uwierzytelniania prosi skonfigurowanego dostawcę użytkownika o zwrócenie obiektu użytkownika dla danego argumentu (tutaj e-mail). Więc owerrider UserManger, aby zachować dopasowanie do dokumentu. Po prostu podążam za dokumentem, aby upewnić się, że jest to najlepsza praktyka. Mam nadzieję, że rozumiesz, co chciałbym zrobić i może ci pomóc, jeśli będziesz tego potrzebować. –

+1

Teraz jest dla mnie jasne, muszę się dużo nauczyć i czytać dokumentację na temat bezpieczeństwa w Symfony. Poszukuję tego i na pewno zastosuję Twoją logikę, aby zapewnić maksymalną liczbę przypadków użycia. Dzięki za odpowiedź. – chalasr

+0

Nie ma za co. Zamieszczam to pytanie, aby mieć pewność, że utworzyłem odpowiednią praktykę/metodę i mam inne sugestie dla programistów, jeśli tak nie jest. Jestem szczęśliwy, jeśli to może ci pomóc. –

Powiązane problemy