在Symfony 2.8/3.0中,使用新的安全组件时,如何在服务中获取当前已登录的User
对象(即FOSUser),而不必注入整个容器?
这是否有可能以一种非hacky的方式实现?
注:请不要考虑“将其作为参数传递给服务函数”的方法,因为它过于明显和不规范。
在Symfony 2.8/3.0中,使用新的安全组件时,如何在服务中获取当前已登录的User
对象(即FOSUser),而不必注入整个容器?
这是否有可能以一种非hacky的方式实现?
注:请不要考虑“将其作为参数传递给服务函数”的方法,因为它过于明显和不规范。
将security.token_storage
服务注入到您的服务中,然后使用:
$this->token_storage->getToken()->getUser();
如此描述:http://symfony.com/doc/current/book/security.html#retrieving-the-user-object 和 http://symfony.com/doc/current/book/service_container.html#referencing-injecting-services
适用于Symfony 3.4、4.x、5.x及以上版本。安全实用类是在Symfony 3.4中引入的。
use Symfony\Component\Security\Core\Security;
public function indexAction(Security $security)
{
$user = $security->getUser();
}
https://symfony.com/doc/3.4/security.html#always-check-if-the-user-is-logged-in
Security
而不是 TokenStorageInterface
和/或 AuthorizationCheckerInterface
,因为该类是 final
的,这使得它无法被模拟,进而使单元测试服务依赖于这些服务变得比必要的更加困难。 - Liiva使用构造函数依赖注入,您可以这样做:
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class A
{
private $user;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->user = $tokenStorage->getToken()->getUser();
}
public function foo()
{
dump($this->user);
}
}
$tokenStorage->getToken()
时,我收到了null
。这可能是什么原因?用户已经登录... - Mathias Bader$tokenStorage->getToken()
等于 null
,请尝试将整个 $tokenStorage
存储为类属性,即在 __construct(...)
中:$this->tokenStorage = $tokenStorage
。 - ilooauth
过程可能尚未完成。因此,请存储引用$tokenStorage->getToken()
或改用Symfony\Component\Security\Core\Security
。我无法告诉这两者之间的行为差异。Security
似乎在Symfony 4+中很常见。 - k00ni在 Symfony 4 中:
use Symfony\Component\Security\Core\Security;
class ExampleService
{
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
public function someMethod()
{
$user = $this->security->getUser();
}
}
查看文档:https://symfony.com/doc/current/security.html#retrieving-the-user-object
UserValueResolver
。 https://symfony.com/blog/new-in-symfony-3-2-user-value-resolver-for-controllers
use Symfony\Component\Security\Core\User\UserInterface
public function indexAction(UserInterface $user)
{...}
在Symfony 5.2+和PHP 8.0+中,您还可以使用#[CurrentUser]
属性获取已登录的用户。
namespace App\Controller;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class FooController extends AbstractController
{
public function index(#[CurrentUser] ?User $user)
{
// ...
}
}
IsGranted
属性的保护,您可以让用户键入不可为空的 #[CurrentUser] User $user
。 - COilprotected function getUser()
{
if (!$this->container->has('security.token_storage')) {
throw new \LogicException('The SecurityBundle is not registered in your application.');
}
if (null === $token = $this->container->get('security.token_storage')->getToken()) {
return;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return;
}
return $user;
}
security.token_storage
,那么您就可以开始了。如果你的类继承自控制器
$this->get('security.context')->getToken()->getUser();
或者,如果您可以访问容器元素...
$container = $this->configurationPool->getContainer();
$user = $container->get('security.context')->getToken()->getUser();
http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements
null
。我错过了什么需要设置的东西吗? - Mathias Bader