Вход в систему FOSUserBundle по электронной почте (Symfony2)
У меня есть вопрос о FOSUserBundle для Symfony 2.0.x.
В документации вы можете найти способ изменить логин для работы с именем пользователя и электронной почтой. Это отлично работает! Но я хочу войти, чтобы работать только с электронной почтой. Таким образом, я добавил функцию в свой CustomUserManager (простирается от оригинала), который гарантирует, что вы просто сможете войти в систему с вашей электронной почтой.
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;
}
}
Но теперь у меня есть проблема с тем, что мне нужно контролировать значения, которые сохраняются в сеансе. Он сохраняет мое имя пользователя в сеансе, и когда система проверяет это, не будет электронной почты (потому что он проверяет только электронную почту).
Итак, мой вопрос в том, как/где вы можете изменить значение, которое хранится внутри переменной имени пользователя.
Спасибо!
Ответы
Ответ 1
Это можно сделать, переопределив сеттеры в объекте 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
, а код пакета зависит от него).
Ответ 2
Я нашел очень простое решение, возможно, не самое лучшее, но простота - сила!;)
Я пишу здесь на всякий случай, если это хорошо для всех.
Я помещаю логин/адрес электронной почты в поставщиков:
В app/conf/security.yml:
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
А затем в представлении вашей формы входа я разрешаю только для входа с типом ввода = "email":
<input type="email" class="form-control" id="username" placeholder="E-Mail" name="_username" required="required"/>