ฉันจะรับเอนทิตีที่แสดงถึงผู้ใช้ปัจจุบันใน Symfony2 ได้อย่างไร


137

ฉันใช้การตั้งค่าความปลอดภัยของ Symfony ทุกอย่างทำงานได้ดี แต่ฉันไม่รู้ว่าจะทำสิ่งสำคัญอย่างหนึ่งอย่างไร

ใน twig ฉันสามารถเข้าถึงข้อมูลของผู้ใช้ปัจจุบันได้โดยทำ:

Welcome, {{ app.user.username }}

หรือคล้ายกัน

ฉันจะเข้าถึงข้อมูลเดียวกันนี้ใน Controller ได้อย่างไร โดยเฉพาะอย่างยิ่งฉันต้องการรับเอนทิตีผู้ใช้ปัจจุบันดังนั้นฉันจึงสามารถจัดเก็บอย่างสัมพันธ์กันในเอนทิตีอื่น (การแมปแบบหนึ่งต่อหนึ่ง)

ฉันหวังว่ามันจะเป็นอย่างนั้นจริงๆ

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

แต่ไม่ได้ผล มันทำให้ฉันมีคลาสประเภทหนึ่ง

Symfony\Component\Security\Core\User\User

และฉันต้องการหนึ่งประเภท

Acme\AuctionBundle\Entity\User

ซึ่งเป็นหน่วยงานของฉัน ....


คำตอบ:


211

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คือวัตถุผู้ใช้ของคุณ! คุณไม่จำเป็นต้องสอบถามอีกครั้ง

ค้นหาวิธีตั้งค่าผู้ให้บริการของคุณsecurity.ymlจากเอกสาร Sf2แล้วลองอีกครั้ง

ขอให้โชคดี!


จะเกิดอะไรขึ้นถ้าฉันต้องการเอนทิตีผู้ใช้ในเทมเพลต PHP
DomingoSL

@DomingoSL ตรวจสอบลิงค์ต่อไปนี้จากเอกสารอย่างเป็นทางการ: symfony.com/doc/master/book/…
Cristian Douce

5
ตั้งแต่ Symfony 2.6 บริการ security.context ได้เลิกใช้งานและแยกออกเป็นบริการใหม่สองบริการ ได้แก่ security.authorization_checker และ security.token_storage คุณสามารถตรวจสอบวิธีดึงข้อมูลผู้ใช้ปัจจุบันที่ถูกต้องได้ที่นี่symfony.com/blog/…
jmleroux

1
ฉัน Symfony 5.1.2 และ$user = $this->security->getUser();, $userเสมอnullสำหรับผมไม่ว่าจะเข้าสู่ระบบหรือไม่
Nick Rolando

ดูเหมือนว่าจะเป็นเพราะฉันทำสิ่งนี้ในผู้สมัครสมาชิกกิจกรรมและสิ่งนี้ยังไม่ได้เริ่มต้นในช่วงต้นของคำขอ
Nick Rolando

65

ปฏิบัติที่ดีที่สุด

ตามเอกสารตั้งแต่ 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: ฉันต้อง autowire (Security $ security) เป็นพารามิเตอร์ใน __construct จากนั้นใช้ $ security-> getUser () และvoilà!
tsadiq

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

2
ยินดีต้อนรับสู่ stackoverflow กรุณาอธิบายเกี่ยวกับคำตอบ stackoverflow.com/help/how-to-answer
Rohan Khude

-38

ก่อนอื่นคุณต้องขอชื่อผู้ใช้ของผู้ใช้จากเซสชันในการดำเนินการควบคุมของคุณดังนี้:

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

จากนั้นทำแบบสอบถามไปยังฐานข้อมูลและรับวัตถุของคุณด้วย 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();

ผู้ใช้ $ ควรถือผู้ใช้ด้วยชื่อผู้ใช้นี้ (คุณสามารถใช้ฟิลด์อื่นได้)

... แต่ก่อนอื่นคุณจะต้องกำหนดคอนฟิก /app/config/security.yml ของคุณเพื่อใช้ฟิลด์ที่เหมาะสมสำหรับผู้ให้บริการความปลอดภัยของคุณดังนี้:

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

หวังว่านี่จะช่วยได้!


มาร์ตินคุณต้องการผู้ใช้หรือชื่อผู้ใช้ ทางเลือกเป็นของคุณ เป็นความรับผิดชอบของคุณที่จะได้รับวัตถุที่คุณต้องการ และอย่างที่คุณบอกว่าคุณไม่ต้องการผู้ใช้ทั่วไป แต่เป็นผู้ใช้เนมสเปซของ Acme
ktolis

7
"เลือกคุณจาก Acme \ AuctionBundle \ Entity \ User u โดยที่ u.username =". $ username; = คุณควรใช้คำถาม PARAMETRIZED!
CappY

1
$this->get('security.context')->getToken()->getUser()ตัวเองทำให้คุณเข้าสู่ระบบในวัตถุผู้ใช้ คุณไม่จำเป็นต้องสืบค้นกลับอีกครั้ง คุณใช้เวอร์ชันใดอยู่
Jeet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.