FOSUserBundle email login with service provider, best practice

I was looking to create a service provider for logging in with email, not using FOSUserBundle.

First I wrote this in the security.yml file as per the document here :

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

According to the FOS document, I follow these steps sequentially.

With the exception of MyUserManager.php, I wrote this (according to another stack question 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; } } 

and of course, I modified the User class to implement a specific getter and setter as follows:

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

But I confirm the form of the FOSUser template in app\Resources\FOSUserBundle\views\Security\login.html.twig as follows:

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

Is this a good way to allow a user to only log in with an email field and not a username?

+5
source share
1 answer

Your approach completely restores all the required changes to configure email authentication on FOSUserBundle.

Currently, I used only the same configuration in the entity and security configuration (no template needed because my login is in AJAX). The only doubt I have is the following:

Since the username parameter is always set using the value of the email field, is it useful to create your own CustomUserManager?
The name loadByUsername will work if the username is always equal to email, as your object does in setEmail and setEmailCanonical .

Is it just extra security?

EDIT

Changing the username to the email address may include changing any compliance in the build / validation of the form.

Perhaps you should look at this answer: fooobar.com/questions/112087 / ...

+4
source

Source: https://habr.com/ru/post/1242084/


All Articles