Bagaimana saya mendapatkan entitas yang mewakili pengguna saat ini di Symfony2?

136

Saya menggunakan pengaturan keamanan Symfony. Semuanya berfungsi dengan baik, tetapi saya tidak tahu bagaimana melakukan satu hal penting:

Dalam ranting, saya dapat mencapai info pengguna saat ini dengan melakukan:

Welcome, {{ app.user.username }}

atau serupa

Bagaimana cara mengakses informasi yang sama ini di Controller? Secara khusus, saya ingin mendapatkan entitas pengguna saat ini sehingga saya dapat menyimpannya secara relasional di entitas lain (pemetaan satu-ke-satu).

Aku benar-benar berharap itu akan terjadi

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

tapi itu tidak berhasil. Ini memberi saya kelas tipe

Symfony\Component\Security\Core\User\User

dan saya ingin salah satu tipe

Acme\AuctionBundle\Entity\User

yang merupakan entitas saya ....

Robert Martin
sumber

Jawaban:

209

Symfony 4+, 2019+ Approach

Dalam symfony 4 (mungkin 3.3 juga, tetapi hanya real-diuji dalam 4) Anda dapat menyuntikkan Securitylayanan melalui kabel otomatis di controller seperti ini:

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

Seperti yang dikatakan @ktolis, Anda harus mengkonfigurasi dulu /app/config/security.yml.

Lalu dengan

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

harus enougth!

$useradalah Obyek Pengguna Anda! Anda tidak perlu menanyakannya lagi.

Temukan cara mengatur penyedia Anda security.ymldari Dokumentasi Sf2 dan coba lagi.

Keberuntungan terbaik!

Cristian Douce
sumber
Bagaimana jika saya memerlukan entitas pengguna pada templat PHP?
DomingoSL
@DomingoSL Periksa tautan berikut dari dokumentasi resmi: symfony.com/doc/master/book/…
Cristian Douce
5
Sejak Symfony 2.6, layanan security.context telah ditinggalkan dan dibagi menjadi dua layanan baru: security.authorization_checker dan security.token_storage. Anda dapat memeriksa cara yang benar untuk mengambil pengguna saat ini di sini: symfony.com/blog/...
jmleroux
Saya menggunakan Symfony 5.1.2 dan terus $user = $this->security->getUser();, $userselalu nulluntuk saya, apakah masuk atau tidak.
Nick Rolando
Oh sepertinya itu karena saya melakukan ini di Pelanggan Acara, dan ini belum diinisialisasi ini di awal permintaan.
Nick Rolando
62

Praktek terbaik

Menurut dokumentasi karena Symfony 2.1 cukup gunakan pintasan ini:

$user = $this->getUser();

Di atas masih bekerja pada Symfony 3.2 dan merupakan jalan pintas untuk ini:

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

The security.token_storagelayanan diperkenalkan pada Symfony 2.6. Sebelum ke Symfony 2.6, Anda harus menggunakan getToken()metode security.contextlayanan.

Contoh : Dan jika Anda ingin langsung nama pengguna:

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

Jika tipe kelas pengguna salah

Pengguna akan menjadi objek dan kelas objek itu akan tergantung pada penyedia pengguna Anda .

Subit Antoine
sumber
6

Utasnya agak lama tetapi saya pikir ini mungkin bisa menghemat waktu seseorang ...

Saya mengalami masalah yang sama dengan pertanyaan awal, bahwa jenisnya ditampilkan sebagai Symfony \ Component \ Security \ Core \ User \ User

Akhirnya ternyata saya masuk menggunakan pengguna dalam memori

security.yml saya terlihat seperti ini

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

tipe pengguna in_memory selalu Symfony \ Component \ Security \ Core \ User \ User jika Anda ingin menggunakan entitas Anda sendiri, login menggunakan pengguna penyedia itu.

Terima kasih, hj

hj '
sumber
4

Dalam symfony> = 3.2, dokumentasi menyatakan bahwa:

Cara alternatif untuk mendapatkan pengguna saat ini di controller adalah dengan mengetikkan-petunjuk argumen controller dengan UserInterface (dan default ke null jika login adalah opsional):

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

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

Ini hanya disarankan untuk pengembang berpengalaman yang tidak memperpanjang dari pengendali basis Symfony dan juga tidak menggunakan ControllerTrait . Jika tidak, disarankan untuk tetap menggunakan pintasan getUser ().

Posting blog tentang itu

Nikita U.
sumber
Ini sangat membantu saya ketika mencoba untuk mendapatkan pengguna saat ini di EventSubscriber: saya harus autowire (Security $ security) sebagai param di __construct kemudian gunakan $ security-> getUser () dan voilà!
tsadiq
2
$this->container->get('security.token_storage')->getToken()->getUser();
Alenko Verzina
sumber
2
Selamat datang di stackoverflow. Tolong jelaskan tentang jawabannya. stackoverflow.com/help/how-to-answer
Rohan Khude
-36

Nah, pertama-tama Anda perlu meminta nama pengguna dari sesi dalam aksi controller Anda seperti ini:

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

kemudian lakukan query ke db dan dapatkan objek Anda dengan dql seperti biasa

$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 sekarang harus memegang pengguna dengan nama pengguna ini (Anda juga bisa menggunakan bidang lain tentu saja)

... tetapi Anda harus terlebih dahulu mengkonfigurasi konfigurasi /app/config/security.yml Anda untuk menggunakan bidang yang sesuai untuk penyedia keamanan Anda seperti:

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

semoga ini membantu!

ktolis
sumber
Yah Martin Anda juga ingin pengguna ATAU nama pengguna. Pilihan ada padamu. Adalah tanggung jawab Anda untuk mendapatkan objek yang Anda butuhkan. Dan seperti yang Anda katakan, Anda tidak ingin pengguna biasa tetapi pengguna namespace Acme.
ktolis
6
"PILIH u DARI Acme \ AuctionBundle \ Entity \ User u where u.username =". $ Username; = ANDA HARUS MENGGUNAKAN KUAT PARAMETRI!
CappY
1
$this->get('security.context')->getToken()->getUser()itu sendiri membuat Anda objek pengguna yang masuk. Anda tidak perlu menanyakannya kembali. Sebenarnya, versi apa yang Anda gunakan?
Jeet