Вход в систему FOSUserBundle по электронной почте с поставщиком услуг, лучшая практика


Я хотел создать поставщика услуг, чтобы войти в систему с помощью электронной почты, а не имени пользователя с помощью FOSUserBundle.

Сначала я написал это в своем файле security.yml в соответствии с документом здесь:

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

Согласно документу FOS, я выполняю эти шаги один за другим.

За исключением MyUserManager.php Я написал это (согласно другому вопросу в стеке здесь):

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;

    }
}

И, конечно, я изменил класс пользователя, чтобы реализуйте конкретный геттер и сеттер следующим образом:

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

    // ...

}

Но я использую форму шаблона FOSUser в app\Resources\FOSUserBundle\views\Security\login.html.twig вот так:

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

Это хороший способ разрешить пользователю входить в систему только с полем электронной почты, а не с именем пользователя?

Author: Community, 2016-02-02

1 answers

Ваш подход полностью повторяет все обязательные изменения для настройки аутентификации по паролю электронной почты на FOSUserBundle.

На данный момент я использовал только ту же конфигурацию в конфигурации сущности и безопасности (шаблон не нужен, потому что мой вход выполнен в AJAX). Единственное сомнение, которое у меня есть, заключается в следующем:

Поскольку username всегда задается с помощью значения поля email, полезно ли создавать свой пользовательский менеджер?
Имя пользователя loadByUsername будет работать, если имя пользователя всегда равно на электронное письмо, как это сделано вашей организацией в setEmail и setEmailCanonical.

Это просто дополнительная защита?

РЕДАКТИРОВАТЬ

Изменение имени пользователя на адрес электронной почты может привести к изменению некоторых правил построения/проверки формы.

Возможно, вам стоит взглянуть на этот ответ: https://stackoverflow.com/a/21064627/4363634

 4
Author: chalasr, 2017-05-23 12:25:40