Flo*_*dot 1 php service token symfony
我为需要访问当前登录用户的 prePersist 和 preFlush 事件创建了一个侦听器:
<?php
namespace App\EventListener;
use App\Entity\AbstractEntity;
use App\Entity\User;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Events;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Exception;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use function is_object;
class DatabaseActivitySubscriber implements EventSubscriber
{
/**
* @var TokenInterface|null
*/
private ?TokenInterface $token;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->token = $tokenStorage->getToken();
}
/**
* @return array|string[]
*/
public function getSubscribedEvents()
{
return [
Events::prePersist,
Events::preUpdate,
];
}
/**
* Initialise le nom de l'utilisateur a l'origine de la création sous la forme "Nom Prénom (id)"
*
* @param LifecycleEventArgs $args
* @throws Exception
*/
public function prePersist(LifecycleEventArgs $args)
{
if ($args->getObject() instanceof AbstractEntity) {
$args->getObject()->setCreateUser($this->getUser()->getLastName() . ' ' . $this->getuser()->getLastName() . ' (' . $this->getuser()->getId() . ')');
}
}
/**
* @return string|\Stringable|UserInterface|null|User
*/
private function getUser()
{
if (null === $token = $this->token) {
return null;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return null;
}
return $user;
}
/**
* @param LifecycleEventArgs $args
*/
public function preUpdate(LifecycleEventArgs $args)
{
if ($args->getObject() instanceof AbstractEntity) {
$args->getObject()->setUpdateUser($this->getuser()->getLastName() . ' ' . $this->getuser()->getLastName() . ' (' . $this->getuser()->getId() . ')');
}
}
}
Run Code Online (Sandbox Code Playgroud)
但令牌始终为空。
所以我对控制器中的现有内容进行了一些验证:
/**
* @Route("/create", name="create")
* @param Request $request
* @param TrainingManager $trainingManager
* @return Response
*/
public function create(Request $request, TrainingManager $trainingManager)
{
$training = new Training();
$form = $this->createForm(FormNameType::class, $training);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $this->getUser();
$trainingManager->save($training);
}
return $this->render('create.html.twig', ['form' => $form->createView(),]);
}
Run Code Online (Sandbox Code Playgroud)
并且用户可以很好地检索 $this->getUser(); 紧随其后的行,我的 dataBaseSubscriber 已启动,并且在构造函数中令牌为空。实际上相同的令牌。
我检查了“security.token_storage”是否正确自动装配,我还尝试在 service.yml 中强制执行
这让我很困惑。UsageTrackingStorage 的这两个实例之间的唯一区别是一个用于控制器,另一个用于订阅者。但它应该注入相同的实例......
订阅者(比如您的订阅者)很可能在请求生命周期的早期就被初始化。也就是说,在为所有身份验证内容拆分请求之前。
TokenStorage 是正确的,但是,在您的订阅者被初始化(读取:__construct被调用)的那一刻,除了对象本身之外几乎没有任何东西存在,但它仍然是空的(显然)。有/可以有 EventSubscribers 可以更改身份验证过程,因此如果令牌已经存在于那里,那将是荒谬的。(事实上,我相信 symfony 中的身份验证是通过 EventListeners 完成的)。
因此,当在该点getToken()上调用它时,它返回 null,因为它不持有任何标记,但稍后会添加这些标记。
解决方案非常简单:只需存储 TokenStorage - 而不是(空)令牌 - 稍后在您真正需要它时调用“getToken”并且那里实际上有令牌。开销几乎可以忽略不计(缓存可能是可能的,但没有看到很好的理由)。
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |