1

我想在 Symfony 4.3.2 项目的控制器构造器中获取用户对象。根据https://symfony.com/doc/4.0/security.html#retrieving-the-user-object上的文档,我只需要调用 $this->getUser()。是的,这适用于行动方法。

但是:尝试在构造函数中获取用户不起作用,因为容器不会在此处初始化,并且 getUser 方法会引发异常“调用成员函数 has() on null”:此时容器为 null及时。

这有效:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class TestController extends AbstractController
{
    public function indexAction()
    {
        dump($this->getUser());
    }
}

这不会:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class TestController extends AbstractController
{
    public function __contruct()
    {
        dump($this->getUser());
    }

    public function indexAction()
    {
    }
}

当我手动注入容器时,一切都很好:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class TestController extends AbstractController
{
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        dump($this->getUser());
    }

    public function indexAction()
    {
    }
}

顺便说一句,这是 AbstractController 中的 getUser 方法:

    protected function getUser()
    {
        if (!$this->container->has('security.token_storage')) {
            throw new \LogicException('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle".');
        }
    ...... 

这是一个错误,容器未在构造函数中初始化,还是一个特性,当您需要构造函数中的用户时,您必须手动初始化它?

编辑:使用https://symfony.com/blog/new-in-symfony-3-2-user-value-resolver-for-controllers中显示的方式在动作中起作用,但在构造函数中不起作用:

    ....
    private $user;

    public function __construct(UserInterface $user)
    {
        $this->user = $user;
    }

产生以下错误消息:Cannot autowire service "App\Controller\TestController": argument "$user" of method "__construct()" references interface "Symfony\Component\Security\Core\User\UserInterface" but no such service exists. Did you create a class that implements this interface?。这就是我想设置用户对象的地方。

4

2 回答 2

3

切勿使用 $security->getUser()$this->getUser() 在构造函数中!

身份验证可能尚未完成。(在 Service 中,存储整个 Security 对象。:

symfony.com/doc/security.html#a-fetching-the-user-object

...并且您可以$this->getUser()在任何控制器中使用通过 AbstractController 扩展的内容。(只是不在构造函数中)

于 2019-08-10T02:59:17.877 回答
0

在通过调用您提到的方法实例化控制器ControllerResolver 之后,容器被设置。setContainer因此,当调用构造函数时,容器在设计上是不可用的。

您可能有一个用例,但我不明白您为什么要这样做,因为在您的控制器方法中,您必须访问该$user属性,它只会让您节省键入get(). 您可以注入示例中所示的整个容器,也可以只注入Security服务。

use Symfony\Component\Security\Core\Security;

class TestController extends AbstractController
{
    private $user;

    public function __construct(Security $security)
    {
        $this->user = $security->getUser();
    }

    public function indexAction()
    {
        $user = $this->user; // Just saved you typing five characters
        // At this point the container is available
    }
}

我实际上并没有设置安全服务,因为它稍后会通过容器变得可用。

如果您想这样做以对整个班级实施访问控制,您可以使用Security 注释

use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;

/**
 * @IsGranted('ROLE_USER')
 */
class TestController extends AbstractController
{
     // Only authenticated user will be able to access this methods
}
于 2019-08-09T22:03:27.253 回答