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

Posted

技术标签:

【中文标题】FOSUserBundle 使用电子邮件登录 (Symfony2)【英文标题】:FOSUserBundle login with email (Symfony2) 【发布时间】:2012-05-06 02:16:01 【问题描述】:

我有一个关于 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;

    

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

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

谢谢!

【问题讨论】:

【参考方案1】:

这可以通过覆盖用户实体中的设置器来完成:

<?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 需要 username 属性,并且捆绑代码依赖它)。

【讨论】:

【参考方案2】:

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

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

我将用户名/电子邮件登录选项放在提供者中:

在 app/conf/security.yml 中:

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

然后在您的登录表单中,我只允许使用输入 type="email" 登录:

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

【讨论】:

嘿,感谢这个 NoFlag - 这对我来说非常有效。我在配置参考中寻找它。但是,因为这实际上是在安全配置中,它不在FOSUserBundle configuration reference 中。对于与我做同样事情的其他人 - 您必须在 security configuration docs for FOSUserBundle 中查找。 html5输入类型,仅适用于最近的浏览器 虽然这可行并且无论如何都有意义,但请记住,用户可以打开开发工具并将type="email"更改为type="text",然后使用用户名登录。显然,这是否会成为问题取决于您的情况。 github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/…

以上是关于FOSUserBundle 使用电子邮件登录 (Symfony2)的主要内容,如果未能解决你的问题,请参考以下文章

FOSUserBundle 配置文件上的电子邮件确认编辑

symfony2:使用 fosuserbundle 登录后使用引用

使用 FOSUserBundle 自动登录 Symfony2 [重复]

将 JSON 数据发布到 FOSUserBundle 注册、登录、个人资料等

在FOSUserBundle中登录后的自定义错误消息

Symfony2 在未登录时将 /admin/* 重定向到 /admin/login(或使用 FOSUserBundle?)