首页 文章

FOSUserBundle使用电子邮件登录(Symfony2)

提问于
浏览
14

我有一个关于Symfony 2.0.x的FOSUserBundle的问题 . 在那里,您可以找到一种方法来更改登录名,以使用用户名和电子邮件 . 这很棒!但我想登录只使用电子邮件 . 所以我在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;

    }
}

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

所以我的问题是如何/在哪里可以更改存储在username变量中的值 .

谢谢!

2 回答

  • 27

    这可以通过覆盖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 需要用户名属性,捆绑代码依赖于它) .

  • 14

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

    我在这里写下来,以防万一对任何人都有好处 .

    我在提供商中添加了用户名/电子邮件登录选项:

    在app / conf / security.yml中:

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
    

    然后在您的登录表单视图中,我只允许使用input type =“email”登录:

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

相关问题