15

Symfony2.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変数内に格納されている値をどのように/どこで変更できるかということです。

ありがとう!

4

2 に答える 2

27

これは、ユーザーエンティティのセッターをオーバーライドすることで実行できます。

<?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のドキュメント、例「b」による)。

そうすると、フォームとテンプレートを簡単にオーバーライドusernameして、UIからフィールドを削除し、それらをフィールドに置き換えることができemailます。上記のようにメールセッターを上書きしたので、usernameプロパティは適切に入力されます。

これは機能しますが、あまり良い解決策ではありません。欠点は、データベースusernameに列が残っていることです。usernameCanonical当初はこれらを完全に削除したかったのですが、これにはFOSUserBundleでの変更が多すぎる必要があります(ユーザー名属性はで必要\FOS\UserBundle\Model\UserInterfaceであり、バンドルコードはそれに依存します)。

于 2012-04-25T12:33:07.577 に答える
16

私は本当に単純な解決策を見つけました。おそらく最善ではありませんが、単純さは力です!;)

誰かに良い場合に備えて、ここに書き留めておきます。

ユーザー名/メールログインオプションをプロバイダーに追加しました。

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"/>
于 2014-05-07T10:29:28.473 に答える