Symfony2で現在のユーザーを表すエンティティを取得するにはどうすればよいですか?


136

Symfonyのセキュリティ設定を使用しています。すべてが正常に動作しますが、1つの重要なことを行う方法がわかりません。

小枝で、私は現在のユーザーの情報に到達することができます:

Welcome, {{ app.user.username }}

または類似

コントローラでこれと同じ情報にアクセスするにはどうすればよいですか?具体的には、現在のユーザーエンティティを取得して、別のエンティティに関係的に格納できるようにします(1対1マッピング)。

私はそれがなることを本当に望んでいました

$this->get('security.context')->getToken()->getUser()

しかし、それはうまくいきません。それは私にタイプのクラスを与えます

Symfony\Component\Security\Core\User\User

そして私はタイプの1つが欲しい

Acme\AuctionBundle\Entity\User

これは私の実体です...


回答:


209

symfony 4 +、2019 +アプローチ

symfony 4(おそらく3.3でも、4で実際にテストされただけ)では、次のようにコントローラーの自動配線Security介してサービスを注入できます:

<?php

use Symfony\Component\Security\Core\Security;

class SomeClass
{
    /**
     * @var Security
     */
    private $security;

    public function __construct(Security $security)
    {
       $this->security = $security;
    }

    public function privatePage() : Response
    {
        $user = $this->security->getUser(); // null or UserInterface, if logged in
        // ... do whatever you want with $user
    }
}

symfony 2-アプローチ

@ktolisが言うように、最初にを設定する必要があります/app/config/security.yml

次に

$user = $this->get('security.token_storage')->getToken()->getUser();
$user->getUsername();

なすべきだ!

$userユーザーオブジェクトです!もう一度クエリする必要はありません。

Sf2ドキュメンテーションsecurity.ymlからプロバイダーをセットアップする方法を見つけて、再試行してください。

幸運!


PHPテンプレートにユーザーエンティティが必要な場合はどうなりますか?
DomingoSL 2013

:公式ドキュメントから次のリンクをチェック@DomingoSL symfony.com/doc/master/book/...
クリスティアン・ドゥース

5
Symfony 2.6以降、security.contextサービスは非推奨となり、security.authorization_checkerとsecurity.token_storageの2つの新しいサービスに分割されました。あなたはここに現在のユーザーを取得するために正しい方法を確認することができます。symfony.com/blog/...
jmleroux

私はsymfony 5.1.2上とによ$user = $this->security->getUser();$user常にnullではないか、ログインしているかどうか、私のために。
Nick Rolando

ああ、それは私がイベントサブスクライバーでこれを行っているためであり、これはリクエストの初期段階ではまだ初期化されていません。
Nick Rolando

62

ベストプラクティス

Symfony 2.1以降のドキュメントによると単にこのショートカットを使用します:

$user = $this->getUser();

上記はまだSymfony 3.2で動作しており、これのショートカットです:

$user = $this->get('security.token_storage')->getToken()->getUser();

このsecurity.token_storageサービスはSymfony 2.6で導入されました。Symfony 2.6以前でgetToken()は、security.contextサービスのメソッドを使用する必要がありました。

:直接ユーザー名が必要な場合:

$username = $this->getUser()->getUsername();

ユーザークラスタイプが間違っている場合

ユーザーはオブジェクトであり、そのオブジェクトのクラスはユーザープロバイダーによって異なります


6

スレッドは少し古いですが、これはおそらく誰かの時間を節約できると思います...

タイプがSymfony \ Component \ Security \ Core \ User \ Userとして表示されるという、元の質問と同じ問題が発生しました

最終的に、メモリ内ユーザーを使用してログインしていることがわかりました

私のsecurity.ymlはこのようなものです

security:
    providers:
        chain_provider:
            chain:
                providers: [in_memory, fos_userbundle]
        fos_userbundle:
            id: fos_user.user_manager
        in_memory:
            memory:
                users:
                    user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                    admin: { password: adminpass, roles: [ 'ROLE_ADMIN', 'ROLE_SONATA_ADMIN' ] }

独自のエンティティを使用する場合、in_memoryユーザータイプは常にSymfony \ Component \ Security \ Core \ User \ Userです。そのプロバイダーのユーザーを使用してログインします。

ありがとう、hj


4

symfony> = 3.2では、ドキュメントは次のように述べています:

コントローラーで現在のユーザーを取得する別の方法は、UserInterfaceを使用してコントローラーの引数をタイプヒントすることです(ログインしている場合はデフォルトでnullになります)。

use Symfony\Component\Security\Core\User\UserInterface\UserInterface;

public function indexAction(UserInterface $user = null)
{
    // $user is null when not logged-in or anon.
}

これは、Symfonyベースコントローラーから拡張せず、ControllerTrait も使用しない経験豊富な開発者にのみ推奨されます。それ以外の場合は、getUser()ショートカットを引き続き使用することをお勧めします。

それに関するブログ投稿


これは、EventSubscriberで現在のユーザーを取得する際に非常に役立ちました。__constructのパラメーターとして(Security $ security)を自動配線し、$ security-> getUser()とvoilàを使用する必要がありました。
tsadiq 2018


-36

さて、最初に、次のようなコントローラーアクションのセッションからユーザーのユーザー名を要求する必要があります。

$username=$this->get('security.context')->getToken()->getUser()->getUserName();

次に、dbにクエリを実行し、通常のdqlを使用してオブジェクトを取得します

$em = $this->get('doctrine.orm.entity_manager');    
"SELECT u FROM Acme\AuctionBundle\Entity\User u where u.username=".$username;
$q=$em->createQuery($query);
$user=$q->getResult();

$ userはこのユーザー名を持つユーザーを保持する必要があります(もちろん他のフィールドを使用することもできます)

...しかし、最初に/app/config/security.yml設定を設定して、セキュリティプロバイダーに適切なフィールドを使用する必要があります:

security:
 provider:
  example:
   entity: {class Acme\AuctionBundle\Entity\User, property: username}

お役に立てれば!


さてマーティンは、ユーザーかユーザー名のどちらかが欲しいです。選択はあなた次第です。必要なオブジェクトを取得するのはあなたの責任です。そして、あなたが言ったように、通常のユーザーではなくAcme名前空間のユーザーが必要です。
ktolis

6
"Select u FROM Acme \ AuctionBundle \ Entity \ User u where u.username ="。$ username; =パラメータ化されたクエリを使用する必要があります!
CappY 2013年

1
$this->get('security.context')->getToken()->getUser()それ自体が、ログインしたユーザーオブジェクトを取得します。もう一度クエリする必要はありません。実際、どのバージョンを使用していましたか?
Jeet
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.