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?
source share