简体   繁体   English

Symfony 2.8:无法在服务中获取当前用户(FosUserBundle)

[英]Symfony 2.8: Cannot get current user in Service (FosUserBundle)

I am trying to access the user inside a service in order to keep track of latest activity. 我试图访问服务内的用户,以便跟踪最新活动。 However it throws an error: 但是它抛出一个错误:

Error: Call to a member function getUser() on a non-object 错误:在非对象上调用成员函数getUser()

but if I var_dump and die() the user object I can see the information. 但是如果我使用var_dumpdie() 用户对象 ,则可以看到该信息。

Any ideas ? 有任何想法吗 ?

ActivityListener ActivityListener

<?php

namespace AppBundle\EventListener;

use AppBundle\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class ActivityListener
{
    protected $tokenStorage;
    protected $em;

    public function __construct(TokenStorage $tokenStorage, \Doctrine\ORM\EntityManager $em)
    {
        $this->tokenStorage     =   $tokenStorage;
        $this->em               =   $em;
    }

    public function onCoreController(FilterControllerEvent $event)
    {
        $user = $this->tokenStorage->getToken()->getUser();

        if($user instanceof User)
        {
            $user->setLastActive(new \DateTime());

            $this->em->persist($user);
            $this->em->flush($user);
        }
    }
}

services.yml services.yml

 app.activityListener:class: AppBundle\EventListener\ActivityListener
     arguments: [ @security.token_storage, @doctrine.orm.entity_manager ]
     tags: - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }

As you can see here: 如您所见:

/**
 * Returns the current security token.
 *
 * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available
 */
public function getToken();

getToken() can return TokenInterface object or null (when user is not logged in). getToken getToken()可以返回TokenInterface对象或null (当用户未登录时)。

Change your method to this: 将您的方法更改为此:

public function onCoreController(FilterControllerEvent $event)
{
    if (is_null($token = $this->tokenStorage->getToken())) {
        return;
    }

    $user = $token->getUser();

    if($user instanceof User)
    {
        $user->setLastActive(new \DateTime());

        $this->em->persist($user);
        $this->em->flush($user);
    }
}

And if you see User object on var_dump and die() then it must be the case when listener is called more times than one and then it don't have user information. 而且,如果您在var_dumpdie()上看到User对象,则一定是这种情况,即侦听器被调用多次而不是没有用户信息。 Try to just echo something here to validate my theory (with echo before return). 尝试在此处回声以验证我的理论(返回前回声)。 It can be connected with sub-requests and missing authentication data. 它可以与子请求和丢失的身份验证数据连接。

Like the previous person said, the code probably goes over the event listener multiple times. 就像前面的人说的那样,代码可能多次遍历事件侦听器。 I'd check if the request is a master request, and if not, move on. 我会检查请求是否是主请求,如果不是,请继续。 After that, load the user from the token and check if it actually is a User object, because it could very well not be, if not, again move on. 之后,从令牌中加载用户并检查它是否实际上是一个User对象,因为它很可能不会再继续前进(如果不是)。

public function onCoreController(FilterControllerEvent $event)
{
    if (!$event->isMasterRequest() || !$this->tokenStorage->getToken()) {
        return;
    }

    $user = $this->tokenStorage->getToken()->getUser();

    if (!$user instanceof User) {
        return;
    }

    $user->setLastActive(new \DateTime());
    $this->em->persist($user);
    $this->em->flush($user);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM