Wie erhalte ich die Entität, die den aktuellen Benutzer in Symfony2 darstellt?

136

Ich verwende das Symfony-Sicherheits-Setup. Alles funktioniert gut, aber ich weiß nicht, wie ich eine wichtige Sache machen soll:

Im Zweig kann ich die Informationen des aktuellen Benutzers erreichen, indem ich Folgendes mache:

Welcome, {{ app.user.username }}

o.ä

Wie greife ich im Controller auf dieselben Informationen zu? Insbesondere möchte ich die aktuelle Benutzerentität abrufen, damit ich sie relational in einer anderen Entität speichern kann (Eins-zu-Eins-Zuordnung).

Ich hatte wirklich gehofft, dass es so sein würde

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

aber das funktioniert nicht. Es gibt mir eine Klasse von Typ

Symfony\Component\Security\Core\User\User

und ich möchte einen Typ

Acme\AuctionBundle\Entity\User

Welches ist meine Entität ....

Robert Martin
quelle

Antworten:

209

Symfony 4+, 2019+ Ansatz

In Symfony 4 (wahrscheinlich auch 3.3, aber nur in 4 getestet) können Sie den SecurityDienst über die automatische Verkabelung in den Controller wie folgt einspeisen :

<?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- Ansatz

Wie @ktolis sagt, müssen Sie zuerst Ihre konfigurieren /app/config/security.yml.

Dann mit

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

sollte genug sein!

$userist dein Benutzerobjekt! Sie müssen es nicht erneut abfragen.

Finden Sie in security.ymlder Sf2-Dokumentation heraus, wie Sie Ihre Provider einrichten können, und versuchen Sie es erneut.

Bestes Glück!

Cristian Douce
quelle
Was ist, wenn ich die Benutzerentität auf einer PHP-Vorlage benötige?
DomingoSL
@ DomingoSL Überprüfen Sie den folgenden Link aus der offiziellen Dokumentation: symfony.com/doc/master/book/…
Cristian Douce
5
Seit Symfony 2.6 ist der Dienst security.context veraltet und in zwei neue Dienste aufgeteilt: security.authorization_checker und security.token_storage. Sie können den korrekten Weg zum Abrufen des aktuellen Benutzers hier überprüfen
jmleroux
Ich bin auf Symfony 5.1.2 und auf $user = $this->security->getUser();, $userist immer nullfür mich, ob angemeldet oder nicht.
Nick Rolando
Oh, anscheinend liegt es daran, dass ich dies in einem Event-Abonnenten mache, und dies ist noch nicht so früh in der Anfrage initialisiert.
Nick Rolando
62

Beste Übung

Verwenden Sie laut Dokumentation seit Symfony 2.1 einfach diese Verknüpfung:

$user = $this->getUser();

Das Obige funktioniert noch unter Symfony 3.2 und ist eine Abkürzung dafür:

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

Der security.token_storageDienst wurde in Symfony 2.6 eingeführt. Vor Symfony 2.6 mussten Sie die getToken()Methode des security.contextDienstes verwenden.

Beispiel : Und wenn Sie direkt den Benutzernamen wollen:

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

Wenn falscher Benutzerklassentyp

Der Benutzer ist ein Objekt und die Klasse dieses Objekts hängt von Ihrem Benutzeranbieter ab .

Antoine Subit
quelle
6

Der Thread ist ein bisschen alt, aber ich denke, das könnte wahrscheinlich jemandem Zeit sparen ...

Ich bin auf dasselbe Problem gestoßen wie bei der ursprünglichen Frage, dass der Typ als Symfony \ Component \ Security \ Core \ User \ User angezeigt wird

Es stellte sich schließlich heraus, dass ich mit einem In-Memory-Benutzer angemeldet war

Meine security.yml sieht ungefähr so ​​aus

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' ] }

Der Benutzertyp in_memory lautet immer Symfony \ Component \ Security \ Core \ User \ User. Wenn Sie Ihre eigene Entität verwenden möchten, melden Sie sich mit dem Benutzer dieses Anbieters an.

Danke, hj

hj '
quelle
4

In symfony> = 3.2 heißt es in der Dokumentation :

Eine alternative Möglichkeit, den aktuellen Benutzer in einem Controller abzurufen, besteht darin, das Controller-Argument mit UserInterface zu tippen (und standardmäßig auf null zu setzen, wenn die Anmeldung optional ist):

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

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

Dies wird nur erfahrenen Entwicklern empfohlen, die nicht vom Symfony-Basiscontroller ausgehen und auch ControllerTrait nicht verwenden. Andernfalls wird empfohlen, weiterhin die Verknüpfung getUser () zu verwenden.

Blogpost darüber

Nikita U.
quelle
Dies hat mir sehr geholfen, als ich versucht habe, einen aktuellen Benutzer in einem EventSubscriber zu finden: Ich musste automatisch (Security $ security) als Parameter in __construct verdrahten und dann $ security-> getUser () und voilà verwenden!
Tsadiq
2
$this->container->get('security.token_storage')->getToken()->getUser();
Alenko Verzina
quelle
2
Willkommen bei stackoverflow. Bitte erläutern Sie die Antwort. stackoverflow.com/help/how-to-answer
Rohan Khude
-36

Nun, zuerst müssen Sie den Benutzernamen des Benutzers aus der Sitzung in Ihrer Controller-Aktion wie folgt anfordern:

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

Führen Sie dann eine Abfrage an die Datenbank durch und holen Sie sich Ihr Objekt mit regulärem dql like

$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();

Der $ user sollte nun den Benutzer mit diesem Benutzernamen halten (Sie können natürlich auch andere Felder verwenden).

... aber Sie müssen zuerst Ihre /app/config/security.yml-Konfiguration konfigurieren, um das entsprechende Feld für Ihren Sicherheitsanbieter wie folgt zu verwenden:

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

hoffe das hilft!

ktolis
quelle
Nun Martin, du willst entweder den Benutzer oder den Benutzernamen. Es ist deine Entscheidung. Es liegt in Ihrer Verantwortung, das Objekt zu erhalten, das Sie benötigen. Und wie Sie sagten, möchten Sie nicht den regulären Benutzer, sondern den Acme-Namespace-Benutzer.
Ktolis
6
"SELECT u FROM Acme \ AuctionBundle \ Entity \ User u wobei u.username =". $ Username; = SIE SOLLTEN PARAMETRIZIERTE FRAGEN VERWENDEN!
CappY
1
$this->get('security.context')->getToken()->getUser()selbst erhältst du das angemeldete Benutzerobjekt. Sie müssen es nicht erneut abfragen. Welche Version haben Sie tatsächlich verwendet?
Jeet