Comment obtenir l'entité qui représente l'utilisateur actuel dans Symfony2?

136

J'utilise la configuration de sécurité Symfony. Tout fonctionne bien, mais je ne sais pas comment faire une chose importante:

Dans twig, je peux accéder aux informations de l'utilisateur actuel en faisant:

Welcome, {{ app.user.username }}

ou similaire

Comment accéder à ces mêmes informations dans le contrôleur? Plus précisément, je souhaite obtenir l'entité utilisateur actuelle afin de pouvoir la stocker de manière relationnelle dans une autre entité (mappage un-à-un).

J'espérais vraiment que ce serait

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

mais cela ne fonctionne pas. Ça me donne une classe de type

Symfony\Component\Security\Core\User\User

et j'en veux un de type

Acme\AuctionBundle\Entity\User

qui est mon entité ...

Robert Martin
la source

Réponses:

209

Approche Symfony 4+, 2019+

Dans symfony 4 (probablement 3.3 également, mais seulement testé en 4), vous pouvez injecter le Securityservice via un câblage automatique dans le contrôleur comme ceci:

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

Comme le dit @ktolis, vous devez d'abord configurer votre /app/config/security.yml.

Puis avec

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

devrait être suffisant!

$userest votre objet utilisateur! Vous n'avez pas besoin de l'interroger à nouveau.

Découvrez la façon de configurer vos fournisseurs dans security.ymlde Sf2 Documentation et essayez à nouveau.

Bonne chance!

Cristian Douce
la source
Et si j'ai besoin de l'entité utilisateur sur un modèle PHP?
DomingoSL
@DomingoSL Consultez le lien suivant de la documentation officielle: symfony.com/doc/master/book/…
Cristian Douce
5
Depuis Symfony 2.6, le service security.context est obsolète et divisé en deux nouveaux services: security.authorization_checker et security.token_storage. Vous pouvez vérifier la bonne façon de récupérer l'utilisateur actuel ici: symfony.com/blog/…
jmleroux
Je suis sur Symfony 5.1.2 et plus $user = $this->security->getUser();, $userc'est toujours nullpour moi, que vous soyez connecté ou non.
Nick Rolando le
Oh, il semble que c'est parce que je fais cela dans un abonné d'événement, et ce n'est pas encore initialisé si tôt dans la demande.
Nick Rolando le
62

Meilleur entrainement

Selon la documentation depuis Symfony 2.1, utilisez simplement ce raccourci:

$user = $this->getUser();

Ce qui précède fonctionne toujours sur Symfony 3.2 et est un raccourci pour cela:

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

Le security.token_storageservice a été introduit dans Symfony 2.6. Avant Symfony 2.6, vous deviez utiliser la getToken()méthode du security.contextservice.

Exemple : Et si vous voulez directement le nom d'utilisateur:

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

Si le type de classe d'utilisateurs est incorrect

L'utilisateur sera un objet et la classe de cet objet dépendra de votre fournisseur d'utilisateur .

Antoine Subit
la source
6

Le fil est un peu vieux mais je pense que cela pourrait probablement faire gagner du temps à quelqu'un ...

J'ai rencontré le même problème que la question d'origine, à savoir que le type est affiché comme Symfony \ Component \ Security \ Core \ User \ User

Il s'est finalement avéré que j'étais connecté en utilisant un utilisateur en mémoire

mon security.yml ressemble à quelque chose comme ça

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

le type d'utilisateur in_memory est toujours Symfony \ Component \ Security \ Core \ User \ User si vous souhaitez utiliser votre propre entité, connectez-vous en utilisant l'utilisateur de ce fournisseur.

Merci, hj

hj '
la source
4

Dans symfony> = 3.2, la documentation indique que:

Une autre façon d'obtenir l'utilisateur actuel dans un contrôleur consiste à saisir l'argument du contrôleur avec UserInterface (et à le définir par défaut sur null si la connexion est facultative):

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

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

Ceci n'est recommandé que pour les développeurs expérimentés qui ne s'étendent pas à partir du contrôleur de base Symfony et n'utilisent pas le ControllerTrait non plus. Sinon, il est recommandé de continuer à utiliser le raccourci getUser ().

Article de blog à ce sujet

Nikita U.
la source
Cela m'a beaucoup aidé en essayant d'obtenir l'utilisateur actuel dans un EventSubscriber: j'ai dû autowire (Security $ security) en tant que paramètre dans __construct puis utiliser $ security-> getUser () et voilà!
tsadiq
2
$this->container->get('security.token_storage')->getToken()->getUser();
Alenko Verzina
la source
2
Bienvenue dans stackoverflow. Veuillez expliquer la réponse. stackoverflow.com/help/how-to-answer
Rohan Khude
-36

Eh bien, vous devez d'abord demander le nom d'utilisateur de l'utilisateur de la session dans l'action de votre contrôleur comme ceci:

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

puis faites une requête à la base de données et obtenez votre objet avec un dql normal comme

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

le $ user devrait maintenant contenir l'utilisateur avec ce nom d'utilisateur (vous pouvez également utiliser d'autres champs bien sûr)

... mais vous devrez d'abord configurer votre configuration /app/config/security.yml pour utiliser le champ approprié pour votre fournisseur de sécurité comme ceci:

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

J'espère que cela t'aides!

ktolis
la source
Eh bien Martin, vous voulez soit l'utilisateur OU le nom d'utilisateur. Le choix t'appartient. Il est de votre responsabilité d'obtenir l'objet dont vous avez besoin. Et comme vous l'avez dit, vous ne voulez pas de l'utilisateur normal mais de l'utilisateur de l'espace de noms Acme.
ktolis
6
"SELECT u FROM Acme \ AuctionBundle \ Entity \ User u où u.username =". $ Username; = VOUS DEVEZ UTILISER DES QUESTIONS PARAMETRIES
CappY
1
$this->get('security.context')->getToken()->getUser()lui-même vous obtient l'objet utilisateur connecté. Vous n'avez pas à le demander à nouveau. En fait, quelle version utilisiez-vous?
Jeet