2012-04-25 7 views
14

Symfony 2.0.xのFOSUserBundleに関する質問があります。 ドキュメントには、ユーザー名と電子メールのどちらでも動作するようにログインを変更する方法が記載されています。それは素晴らしい作品です!しかし、私は電子メールだけで作業するためにログインしたい。だから私はあなたの電子メールでログオンできることを確認する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; 

    } 
} 

しかし、今セッションに保存されている値を制御する必要があるという問題があります。彼はセッションで私のユーザ名を保存し、システムがこれをチェックすると、利用可能な電子メールはありません(彼は電子メールのみをチェックするので)。

私の質問はどのように/あなたはusername変数の中に格納されている値を変更することができますです。

ありがとうございます!

答えて

27

これは、Userエンティティでオーバーライドセッターによって行うことができます。

<?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")。

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

これは機能しますが、それほど素晴らしい解決策ではありません。欠点は、データベースにまだusernameusernameCanonicalの列があることです。もともとはこれらを完全に削除したいと思っていましたが、FOSUserBundleにあまりにも多くの変更が必要でした(username属性は\FOS\UserBundle\Model\UserInterfaceで必要となり、バンドルコードはそれに依存します)。

14

私は本当にシンプルなソリューションを見つけましたが、おそらく最高ではないがシンプルさはパワーです! ;)

私はここに書いていますので、誰にでも分かります。

私はプロバイダにユーザー名/メールのログインオプションを置く:アプリ/ confに/ security.ymlファイルで

providers: 
    fos_userbundle: 
     id: fos_user.user_provider.username_email 

そして私だけで、ログインのために聞かせて、あなたのログインフォームのビューで入力タイプ= "email":

​​
+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

+0

これはhtml5の入力タイプです。最新のブラウザの場合のみ –

+1

これはうまくいくと思いますが、ユーザは開発ツールを開き、 'type =" email "' 'type =" text "'に変更し、ユーザー名でログインします。それは明らかにそれが問題になるかどうかあなたの状況に依存します。 – bassplayer7

関連する問題