Làm cách nào để có được thực thể đại diện cho người dùng hiện tại trong Symfony2?


136

Tôi đang sử dụng thiết lập bảo mật Symfony. Mọi thứ đều hoạt động tốt, nhưng tôi không biết làm một điều quan trọng:

Trong twig, tôi có thể tiếp cận thông tin người dùng hiện tại bằng cách thực hiện:

Welcome, {{ app.user.username }}

hoặc tương tự

Làm cách nào để truy cập cùng thông tin này trong Bộ điều khiển? Cụ thể, tôi muốn có được thực thể người dùng hiện tại để tôi có thể lưu trữ nó một cách tương đối trong một thực thể khác (ánh xạ một-một).

Tôi đã thực sự hy vọng nó sẽ được

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

nhưng nó không hoạt động. Nó cho tôi một lớp loại

Symfony\Component\Security\Core\User\User

và tôi muốn một trong những loại

Acme\AuctionBundle\Entity\User

đó là thực thể của tôi ....


Câu trả lời:


209

Cách tiếp cận Symfony 4+, 2019+

Trong symfony 4 (cũng có thể là 3,3, nhưng chỉ được thử nghiệm thực tế trong 4), bạn có thể tiêm Securitydịch vụ thông qua tự động nối dây trong bộ điều khiển như thế này:

<?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- Cách tiếp cận

Như @ktolis nói, trước tiên bạn phải cấu hình /app/config/security.yml.

Sau đó với

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

nên là khó khăn!

$userlà đối tượng người dùng của bạn! Bạn không cần phải truy vấn nó một lần nữa.

Tìm hiểu cách thiết lập nhà cung cấp của bạn security.ymltừ Tài liệu Sf2 và thử lại.

May mắn nhất!


Điều gì xảy ra nếu tôi cần thực thể người dùng trên một mẫu PHP?
DomingoSL

@DomingoSL Kiểm tra liên kết sau từ tài liệu chính thức: symfony.com/doc/master/book/ mẹo
Cristian Douce

5
Kể từ Symfony 2.6, dịch vụ security.context đã không được dùng nữa và được chia thành hai dịch vụ mới: security. Mượtization_checker và security.token_st Storage. Bạn có thể kiểm tra cách chính xác để tìm nạp người dùng hiện tại tại đây: symfony.com/blog/
mẹo

Tôi đang sử dụng Symfony 5.1.2 trở đi $user = $this->security->getUser();, $userluôn nulldành cho tôi, dù đăng nhập hay không.
Nick Rolando

Có vẻ như đó là vì tôi đang thực hiện việc này trong Người đăng ký Sự kiện và điều này chưa được khởi tạo sớm trong yêu cầu này.
Nick Rolando

62

Thực hành tốt nhất

Theo tài liệu từ Symfony 2.1 chỉ cần sử dụng phím tắt này:

$user = $this->getUser();

Ở trên vẫn đang hoạt động trên Symfony 3.2 và là một phím tắt cho việc này:

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

Các security.token_storagedịch vụ được giới thiệu vào Symfony 2.6. Trước Symfony 2.6, bạn phải sử dụng getToken()phương thức của security.contextdịch vụ.

Ví dụ : Và nếu bạn muốn trực tiếp tên người dùng:

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

Nếu sai loại lớp người dùng

Người dùng sẽ là một đối tượng và lớp của đối tượng đó sẽ phụ thuộc vào nhà cung cấp người dùng của bạn .


6

Chủ đề này hơi cũ nhưng tôi nghĩ rằng điều này có thể tiết kiệm thời gian của ai đó ...

Tôi gặp vấn đề tương tự như câu hỏi ban đầu, loại này được hiển thị là Symfony \ Component \ Security \ Core \ User \ User

Cuối cùng hóa ra tôi đã đăng nhập bằng một người dùng trong bộ nhớ

security.yml của tôi trông giống như thế này

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

loại người dùng in_memory luôn là Symfony \ Element \ Security \ Core \ User \ User nếu bạn muốn sử dụng thực thể của riêng mình, đăng nhập bằng người dùng của nhà cung cấp đó.

Cảm ơn, hj


4

Trong symfony> = 3.2, tài liệu nói rằng:

Một cách khác để có được người dùng hiện tại trong bộ điều khiển là gõ gợi ý đối số của bộ điều khiển với UserInterface (và mặc định nó là null nếu đăng nhập là tùy chọn):

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

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

Điều này chỉ được khuyến nghị cho các nhà phát triển có kinh nghiệm, những người không mở rộng từ bộ điều khiển cơ sở Symfony và cũng không sử dụng Bộ điều khiểnTrait . Mặt khác, bạn nên tiếp tục sử dụng phím tắt getUser ().

Blog bài viết về nó


Điều này đã giúp tôi rất nhiều trong khi cố gắng để có được người dùng hiện tại trong một EventSubscacker: tôi đã phải tự động (Security $ security) là param trong __construct sau đó sử dụng $ security-> getUser () và voilà!
tsadiq

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

2
Chào mừng đến với stackoverflow. Hãy giải thích về câu trả lời. stackoverflow.com/help/how-to-answer
Rohan Khude

-36

Chà, trước tiên bạn cần yêu cầu tên người dùng từ phiên trong hành động điều khiển của bạn như thế này:

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

sau đó thực hiện một truy vấn tới db và nhận đối tượng của bạn với dql thông thường như

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

người dùng $ bây giờ sẽ giữ người dùng với tên người dùng này (tất nhiên bạn cũng có thể sử dụng các trường khác)

... nhưng trước tiên bạn sẽ phải định cấu hình cấu hình /app/config/security.yml của mình để sử dụng trường thích hợp cho nhà cung cấp bảo mật của bạn như vậy:

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

hi vọng điêu nay co ich!


Vâng Martin bạn muốn người dùng HOẶC tên người dùng. Sự lựa chọn là của bạn. Đó là trách nhiệm của bạn để có được đối tượng bạn cần. Và như bạn đã nói, bạn không muốn người dùng thông thường mà là người dùng không gian tên Acme.
ktolis

6
"CHỌN u TỪ Acme \ AuctionBundle \ Entity \ Người dùng u trong đó u.username =". $ Tên người dùng; = BẠN NÊN SỬ DỤNG SỐ LƯỢNG PARAMETRIZED!
CappY

1
$this->get('security.context')->getToken()->getUser()chính nó giúp bạn đăng nhập vào đối tượng người dùng. Bạn không phải truy vấn nó một lần nữa. Trong thực tế, bạn đã sử dụng phiên bản nào?
Jeet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.