Як отримати об’єкт, який представляє поточного користувача в Symfony2?


136

Я використовую налаштування безпеки Symfony. Все працює добре, але я не знаю, як зробити одну важливу річ:

У гілочку я можу отримати інформацію про поточного користувача, виконавши:

Welcome, {{ app.user.username }}

або подібне

Як отримати доступ до цієї ж інформації в Контролері? Зокрема, я хочу отримати поточну сутність користувача, щоб я міг зберігати її відносно в іншому об'єкті (відображення один на один).

Я дуже сподівався, що це буде

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

але це не працює. Це дає мені клас типу

Symfony\Component\Security\Core\User\User

і я хочу одного типу

Acme\AuctionBundle\Entity\User

яка моя сутність ...


Відповіді:


209

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

Симфонія 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

Я перебуваю на Symfony 5.1.2 і далі $user = $this->security->getUser();, $userзавжди nullдля мене, незалежно від того, увійшов чи ні.
Нік Роландо

О, схоже, це тому, що я роблю це в передплатнику події, і це ще не ініціалізовано на початку запиту.
Нік Роландо

62

Найкраща практика

Згідно з документацією, оскільки 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 \ Компонент \ Безпека \ Core \ Користувач \ Користувач, якщо ви хочете використовувати власну сутність, увійдіть, використовуючи користувача цього постачальника.

Дякую, hj


4

У Symfony> = 3.2 документація зазначає, що:

Альтернативний спосіб отримати поточного користувача в контролері - набрати натяк на аргумент контролера за допомогою UserInterface (і за замовчуванням встановити його на нуль, якщо вхід у систему не є обов'язковим):

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: мені довелося автопроводити (Security $ security) як парам в __construct, а потім використовувати $ security-> getUser () та voilà!
tsadiq


-36

Ну, спочатку потрібно запитати ім’я користувача від сеансу в дії контролера так:

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

потім зробіть запит до db і отримайте ваш об'єкт з регулярними подібними 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

6
"SELECT u FROM Acme \ AuctionBundle \ Entity \ User u, де u.username =". $ Username; = ВИ ВИКОРИСТОВУєте ПАРАМЕТРОВАНІ ЗАПИТАННЯ!
CappY

1
$this->get('security.context')->getToken()->getUser()сам отримує вас зареєстрований об’єкт користувача. Вам не доведеться знову його запитувати. Насправді, яку версію ви використовували?
Джет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.