Come ottengo l'entità che rappresenta l'utente corrente in Symfony2?


136

Sto usando il setup di sicurezza di Symfony. Tutto funziona bene, ma non so come fare una cosa importante:

In un ramoscello, posso raggiungere le informazioni dell'utente corrente facendo:

Welcome, {{ app.user.username }}

o simili

Come accedo a queste stesse informazioni nel controller? In particolare, desidero ottenere l'entità utente corrente in modo da poterla archiviare in modo relazionale in un'altra entità (mapping uno a uno).

Speravo davvero che fosse

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

ma non funziona. Mi dà una classe di tipo

Symfony\Component\Security\Core\User\User

e ne voglio uno di tipo

Acme\AuctionBundle\Entity\User

che è la mia entità ....


Risposte:


209

Approccio di Symfony 4+, 2019+

In symfony 4 (probabilmente anche 3.3, ma testato solo in 4) puoi iniettare il Securityservizio tramite l' auto-cablaggio nel controller in questo modo:

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

Come dice @ktolis, devi prima configurare il tuo /app/config/security.yml.

Quindi con

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

dovrebbe essere enougth!

$userè il tuo oggetto utente! Non è necessario interrogarlo di nuovo.

Scopri come impostare i tuoi fornitori security.ymldalla documentazione di Sf2 e riprova.

Buona fortuna!


Cosa succede se ho bisogno dell'entità utente su un modello PHP?
DomingoSL

@DomingoSL Controlla il seguente link dalla documentazione ufficiale: symfony.com/doc/master/book/…
Cristian Douce

5
A partire da Symfony 2.6, il servizio security.context è stato deprecato e suddiviso in due nuovi servizi: security.authorization_checker e security.token_storage. Puoi controllare il modo corretto di recuperare l'utente corrente qui: symfony.com/blog/…
jmleroux

Sono su Symfony 5.1.2 e su $user = $this->security->getUser();, $userè sempre nullper me, sia che abbia effettuato l'accesso o meno.
Nick Rolando,

Oh, sembra che lo stia facendo in un abbonato a un evento, e questo non è ancora inizializzato all'inizio della richiesta.
Nick Rolando,

62

La migliore pratica

Secondo la documentazione di Symfony 2.1 utilizzare semplicemente questo collegamento:

$user = $this->getUser();

Quanto sopra funziona ancora su Symfony 3.2 ed è una scorciatoia per questo:

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

Il security.token_storageservizio è stato introdotto in Symfony 2.6. Prima di Symfony 2.6, dovevi usare il getToken()metodo del security.contextservizio.

Esempio : e se vuoi direttamente il nome utente:

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

Se il tipo di classe utente è errato

L'utente sarà un oggetto e la classe di tale oggetto dipenderà dal provider dell'utente .


6

Il thread è un po 'vecchio ma penso che questo potrebbe probabilmente far risparmiare tempo a qualcuno ...

Ho riscontrato lo stesso problema della domanda originale, che il tipo è mostrato come Symfony \ Component \ Security \ Core \ User \ User

Alla fine si è scoperto che ero loggato usando un utente in memoria

il mio security.yml è simile a questo

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

il tipo di utente in_memory è sempre Symfony \ Component \ Security \ Core \ User \ User se si desidera utilizzare la propria entità, accedere utilizzando l'utente di quel provider.

Grazie, hj


4

In symfony> = 3.2, la documentazione afferma che:

Un modo alternativo per ottenere l'utente corrente in un controller è di suggerire l'argomento controller con UserInterface (e impostarlo su null se l'accesso è facoltativo):

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

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

Questo è consigliato solo per sviluppatori esperti che non si estendono dal controller di base di Symfony e non usano neanche ControllerTrait . Altrimenti, si consiglia di continuare a utilizzare il collegamento getUser ().

Post di blog a riguardo


Questo mi ha aiutato molto nel tentativo di ottenere l'utente corrente in un EventSubscriber: ho dovuto autowire (Security $ security) come parametro in __construct quindi usare $ security-> getUser () e voilà!
Tsadiq,

2
$this->container->get('security.token_storage')->getToken()->getUser();

2
Benvenuto in StackOverflow. Per favore, spiega della risposta. stackoverflow.com/help/how-to-answer
Rohan Khude

-36

Bene, prima devi richiedere il nome utente dell'utente dalla sessione nell'azione del controller in questo modo:

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

quindi esegui una query sul db e ottieni il tuo oggetto con un normale 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 ora dovrebbe contenere l'utente con questo nome utente (puoi ovviamente usare anche altri campi)

... ma dovrai prima configurare la tua configurazione /app/config/security.yml per usare il campo appropriato per il tuo fornitore di sicurezza in questo modo:

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

spero che questo ti aiuti!


Bene Martin, vuoi l'utente o il nome utente. La scelta è tua. È tua responsabilità ottenere l'oggetto di cui hai bisogno. E come hai detto, non vuoi l'utente normale ma l'utente dello spazio dei nomi Acme.
ktolis,

6
"SELEZIONA DA Acme \ AuctionBundle \ Entity \ Utente u dove u.username =". $ Username; = DEVI UTILIZZARE LE DOMANDE PARAMETRIZZATE!
CappY

1
$this->get('security.context')->getToken()->getUser()si ottiene l'oggetto utente registrato. Non è necessario eseguire nuovamente la query. In effetti, quale versione stavi usando?
Jeet
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.