15

我对 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;

    }
}

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

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

谢谢!

4

2 回答 2

27

This can be done by overriding setters in the User entity:

<?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);
    }

    // ...

}

It's not clear from your question, but from your namespaces I assume that you have your own child bundle that uses FOSUserBundle as its parent bundle (as per FOSUserBundle documentation, example "b").

If you do, you can then easily override Forms and templates in order to remove any username fields from the UI and replace them with email fields. Since you have overridden the email setters as per above, username property will be populated properly.

Although this works, it's not a very nice solution. The downside is that you will still have username and usernameCanonical columns in the database. We originally wanted to remove these altogether, but this would require too many changes in FOSUserBundle (the username attribute is required by \FOS\UserBundle\Model\UserInterface, and bundle code depends on it).

于 2012-04-25T12:33:07.577 回答
16

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

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

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

在 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"/>
于 2014-05-07T10:29:28.473 回答