Вопрос по symfony, php – Логин FOSUserBundle с электронной почтой (Symfony2)

14

У меня есть вопрос о FOSUserBundle для Symfony 2.0.x. В этой документации вы можете найти способ изменить логин для работы с именем пользователя и электронной почтой. Это прекрасно работает! Но я хочу войти, чтобы работать только с электронной почтой. Поэтому я добавил в свой CustomUserManager функцию (расширяющуюся от оригинала), которая гарантирует, что вы можете просто войти в систему со своей электронной почтой.

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

    }
}
</code>

Но теперь у меня есть проблема, что мне нужно контролировать значения, которые сохраняются в сессии. Он сохраняет мое имя пользователя в сеансе, и когда система проверит это, электронная почта не будет доступна (потому что он проверяет только электронную почту).

Поэтому мой вопрос заключается в том, как / где вы можете изменить значение, которое хранится в переменной username.

Спасибо!

Ваш Ответ

2   ответа
27

Это можно сделать, переопределив сеттеры в сущности User:

<?php

namespace Acme\UserBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

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

    // ...

}

Это не ясно из вашего вопроса, но из ваших пространств имен я предполагаю, что у вас есть собственный дочерний пакет, который использует FOSUserBundle в качестве родительского пакета (согласноДокументация FOSUserBundle, пример "b").

Если вы это сделаете, вы можете легко переопределить формы и шаблоны, чтобы удалить любыеusername поля из пользовательского интерфейса и заменить ихemail поля. Так как вы переопределили сеттеры электронной почты, как указано выше,username собственность будет заполнена правильно.

Хотя это работает, это не очень хорошее решение. Недостатком является то, что у вас все еще будетusername а такжеusernameCanonical столбцы в базе данных. Изначально мы хотели полностью удалить их, но для этого потребовалось бы слишком много изменений в FOSUserBundle (атрибут имени пользователя требуется\FOS\UserBundle\Model\UserInterfaceи от этого зависит комплектация кода).

14

Я нашел действительно простое решение, возможно, не лучшее, но простота - это сила! ;)

Я пишу здесь на всякий случай, если это кому-нибудь пригодится.

Я поставил имя пользователя / адрес электронной почты для входа в провайдеры:

В app / conf / security.yml:

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

И тогда в виде вашей формы входа я разрешаю только для входа с типом ввода = & quot; email & quot ;:

<input type="email" class="form-control" id="username" placeholder="E-Mail" name="_username" required="required"/>
Хотя это работает и в любом случае имеет смысл сделать это, имейте в виду, что пользователь может открывать инструменты разработчика и изменятьtype="email" вtype="text" а затем войдите в систему с именем пользователя. Очевидно, от вашей ситуации зависит, будет ли это проблемой или нет.
это тип ввода html5, только для последних браузеров
Эй, спасибо за этот NoFlag - это сработало идеально для меня. Я искал это в справочной конфигурации. Но, поскольку это на самом деле в конфигурации безопасности, это не вFOSUserBundle configuration reference, Для всех, кто сделал то же самое, что и я, вы должны искать это вsecurity configuration docs for FOSUserBundle.

Похожие вопросы