#security #symfony #authentication #authorization #bundle
#Безопасность #symfony #аутентификация #авторизация #пакет
Вопрос:
Я хотел бы создать свой пользовательский логин-пакет в symfony 2.5. Я не хочу использовать FOSUserBundle, потому что мой логин-пакет будет работать с другой логикой. Моя логика:
- У пользователя может быть несколько электронных писем, но только для основных электронных писем. Электронные письма будут перечислены в другом объекте (userEmail). Внешний ключ будет ссылаться на идентификатор основного адреса электронной почты
- У пользователя не должно быть имени пользователя или чего-то еще для входа в систему, он может просто использовать адрес электронной почты тех, кто ссылается на его учетную запись (в userEmail)
- Другой объект с именем UserRole будет иметь внешний ключ к идентификатору пользователя с его ролью.
Я уже создал все свои объекты: User, userEmail и UserRole. Итак, я пытаюсь реализовать свой SecurityController. Но, к сожалению, есть некоторые ограничения, которые я нашел в документации:
Чтобы использовать экземпляр класса AcmeUserBundle:User на уровне безопасности Symfony, класс entity должен реализовать UserInterface . Этот интерфейс заставляет класс реализовывать пять следующих методов
getRoles()
getPassword()
getSalt()
getUsername()
eraseCredential()
Таким образом, мой логин не будет включать пункт 4 getUsername()
, потому что у пользователя не будет имени пользователя.
Как я могу реализовать свой вход пользователя без имени пользователя?
Комментарии:
1. Вы не можете использовать адрес электронной почты в качестве имени пользователя?
2. Я не думаю, что это хорошая идея. совершенно непонятно называть его именем пользователя в исходном коде, но это означает адрес электронной почты.
3. Но вы сказали, что у вас нет имени пользователя.
4. Да, у меня нет имени пользователя, и я не хочу называть свой адрес электронной почты «имя пользователя»
5. Вам не нужно переименовывать его, просто создайте его как псевдоним, где GetUserName() вернет адрес электронной почты.
Ответ №1:
Разве вы не можете реализовать метод GetUserName() для возврата идентификатора пользователя? Таким образом, вы можете использовать пользовательский интерфейс.
public function getUsername()
{
return $this->getId();
}
У меня та же проблема, что и у вас. Всем моим пользователям нужен только один адрес электронной почты и пароль для подключения, я не использую никакого имени пользователя. Но мне пришлось реализовать все пользовательские интерфейсы для обработки соединения Symfony, и я использовал вышеупомянутое решение.
Конечно, это вводит в заблуждение, например, в моем коде
public function loadByUsername($username)
{
findBy(array('email' => $username));
....
}
Но я думаю, что это единственное решение прямо сейчас.
Комментарии:
1. Где symfony будет использовать GetUserName()-метод? Возможно, это создаст проблемы
2. Мне противно использовать то, что не было создано для этого. Но если другого способа нет, я должен принять его. Это затруднит понимание моего кода, но нормально.
3. Я не знаю другого способа, но я могу ошибаться. Symfony будет использовать метод GetUserName для отображения текущего зарегистрированного пользователя, например, в профилировщике. Но я знаю, что когда я делаю $this->getUser() в своих контроллерах, я получаю нужного пользователя.
Ответ №2:
если у вас есть объект электронной почты, то он должен быть связан с объектом пользователя, отношение одно ко многим со стороны пользователя, поэтому у вас может быть поле в объекте User, которое содержит массив объектов электронной почты. если функция GetUserName (), вы можете перебирать все электронные письма и возвращать любое из них, которое вы хотите
function getUserName(){
// $Email is an array it will hold the array of email entity
// as it is in one to many relationship with User Entity
foreach($Emails as $email){ // loop through each email
if($email->your_flag_to_identify_primery_username==true){
return $email->email_address; // return that match according to flag set by you
}
далее вы должны написать пользовательский механизм аутентификации эта ссылка будет вам полезна
Ответ №3:
GetUserName() не всегда используется username
в качестве имени поля. Может быть, вы можете взять это в качестве примера, это показывает, как использовать email
в качестве имени поля :
public function getUsername()
{
return $this->email;
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function eraseCredentials()
{
}
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
// see section on salt below
// $this->salt,
));
}
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
Вы также можете использовать array в качестве своего имени пользователя, дайте мне знать, если вы используете array в качестве коллекции своей электронной почты.
ПРИМЕЧАНИЕ: вы все еще можете использовать getEmail() для возврата электронной почты в вашем объекте. Вы можете создать несколько разных имен функций, чтобы возвращать одно и то же поле в вашей сущности. 😉
Ответ №4:
Почему бы не использовать идентификатор в качестве имени пользователя? Это обеспечивает больше логики в вашей концепции: идентификатор уникален, никогда не изменится в течение времени, если вы не измените его вручную. Вы можете отобразить основной адрес электронной почты или список адресов для вашего пользователя, когда вам это нужно. Если вы хотите распознать своего пользователя по какому-либо уникальному свойству, именно для этого следует использовать идентификатор (именно так, как уникальные идентификаторы работают в мире баз данных — это почти тот же вариант использования).
Пример средства получения сущности:
class User {
...
public function getUsername()
{
return $this->id;
}
...
}