FOSUserBundle登录与电子邮件(Symfony2的)

问题描述:

我有一个关于FOSU​​serBundle的Symfony的2.0.x的问题 在那里的文档,你可以找到一种方法来改变登录使用用户名和电子邮件。这很好!但我想登录只用电子邮件。所以我在我的CustomUserManager中添加了一个函数(从原来的扩展),确保您只需登录您的电子邮件。FOSUserBundle登录与电子邮件(Symfony2的)

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; 

    } 
} 

但现在我有一个问题,我需要控制保存在会话中的值。他将我的用户名保存在会话中,当系统检查此消息时,不会有电子邮件(因为他只检查电子邮件)可用。

所以我的问题是如何/在哪里可以改变存储的用户名变量中的值。

谢谢!

这可以通过在用户实体覆盖setter方法来完成:

<?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 documentation,例如“b”)。

如果你这样做,你可以很容易覆盖形式和模板,以便从UI删除任何username领域,并与email领域取代它们。由于您已按上述覆盖了电子邮件设置器,因此username属性将被正确填充。

虽然这个工作,它不是一个非常好的解决方案。缺点是,你仍然会在数据库中usernameusernameCanonical列。我们本来想彻底删除这些,但是这需要在FOSUserBundle(用户名属性由\FOS\UserBundle\Model\UserInterface要求,并捆绑代码依赖于它)太多的变化。

我发现了一个非常简单的解决方案,可能不是最好的,但简单就是力量! ;)

我在这里写下来,以防万一它是很好的人。

我把供应商的用户名/电子邮件登录选项:

在app/conf目录/ security.yml:

providers: 
    fos_userbundle: 
     id: fos_user.user_provider.username_email 

,然后在登录表单的观点我只让与登录输入类型=“电子邮件”:

<input type="email" class="form-control" id="username" placeholder="E-Mail" name="_username" required="required"/> 
+0

嘿,感谢这个NoFlag - 这个工作对我来说是完美的。 我在配置参考中寻找它。但是,因为这实际上在安全配置中,它不在[FOSUserBundle配置参考](https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md)中。对于我做过的同样事情的其他人 - 您必须在[FOSUserBundle的安全配置文档]中查找它(https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/logging_by_username_or_email.md )。 – jfgrissom 2014-06-11 03:41:50

+0

它是html5输入类型,仅适用于最近的浏览器 – 2014-06-18 11:26:32

+1

尽管这样做并且无论如何都有意义,但请记住,用户可以打开开发工具并将'type =“email”'更改为'type =“text”'并且然后使用用户名登录。这显然取决于你的情况,这是否是一个问题。 – bassplayer7 2015-03-02 20:24:55