如何获得在Symfony2中代表当前用户的实体?


136

我正在使用Symfony安全设置。一切正常,但是我不知道如何做一件重要的事情:

在树枝上,我可以通过执行以下操作来获取当前用户的信息:

Welcome, {{ app.user.username }}

或类似

如何在控制器中访问相同的信息?具体来说,我想获取当前的用户实体,以便可以将其关联存储在另一个实体中(一对一映射)。

我真的很希望

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

但这不起作用。它给了我一类类型

Symfony\Component\Security\Core\User\User

我想要一种

Acme\AuctionBundle\Entity\User

这是我的实体...


Answers:


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

Symfony 2-方法

正如@ktolis所说,您首先必须配置/app/config/security.yml

然后用

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

应该是认真的!

$user是您的用户对象!您无需再次查询。

找出设置您的供应商的方式security.ymlSf2的文档,然后再试一次。

好运!


如果我需要PHP模板上的用户实体怎么办?
DomingoSL

@DomingoSL检查从官方文档以下链接:symfony.com/doc/master/book/...
克里斯蒂安·道斯

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 \ 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中的当前用户时对我有很大帮助:我不得不在__construct中自动将(Security $ security)作为参数连接,然后使用$ security-> getUser()和voilà!
tsadiq


-36

好吧,首先您需要在控制器操作中从会话中请求用户的用户名,如下所示:

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

$ user现在应该使用该用户名来保留用户(当然您也可以使用其他字段)

...但是您必须首先配置/app/config/security.yml配置,以使用适用于您的安全提供商的字段,如下所示:

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

希望这可以帮助!


马丁,您要么想要用户,要么想要用户名。这是你的选择。获得所需的对象是您的责任。正如您所说,您不希望普通用户,而是Acme名称空间用户。
ktolis 2011年

6
“从Acme \ AuctionBundle \ Entity \ User u中选择u,其中u.username =”。$ username; =您应该使用参数化查询!
CappY

1
$this->get('security.context')->getToken()->getUser()本身会让您登录的用户对象。您不必再次查询。实际上,您使用的是哪个版本?
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.