symfony中的匿名用户对象

时间:2014-03-03 19:29:35

标签: php symfony doctrine

我使用Symfony提供的基本用户登录/注销系统,只要人们登录就可以正常工作。在这种情况下,$ user对象总是根据需要提供。

问题是当注销(或者还没有进入)时没有用户对象。是否有可能(在这种情况下)使用我自己的默认值提供默认用户对象?

感谢您的建议

4 个答案:

答案 0 :(得分:3)

因为@Chopchop上面提到的解决方案(无论如何,谢谢你的努力)在这里没有用,我写了一些解决方法。

我创建了一个名为myController的新类,它扩展了Controller。我覆盖的唯一函数是getUser()函数。我在那里实现它:

public function getUser()
{
    $user = Controller::getUser();

    if ( !is_object($user) )            
    {
        $user = new \ACME\myBundle\Entity\User();

        $user->setUserLASTNAME ('RaRa');
        $user->setID (0);
        // etc...
    }

    return $user;
}

这对我来说很好。唯一的问题是你必须要小心,不要忘记在所有* Controller.php文件中用myController替换Controller。所以,更好的建议仍然受到欢迎。

答案 1 :(得分:1)

适用于Symfony 3.3

使用@Sfblaauw的建议,我想出了一个使用CompilerPass的解决方案。

的appbundle / AppBundle.php

class AppBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new OverrideAnonymousUserCompilerPass());
    }
}

OverrideAnonymousUserCompilerPass.php

class OverrideAnonymousCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('security.authentication.listener.anonymous');
        $definition->setClass(AnonymousAuthenticationListener::class);
    }
}

AnonymousAuthenticationListener.php

class AnonymousAuthenticationListener implements ListenerInterface
{
    private $tokenStorage;
    private $secret;
    private $authenticationManager;
    private $logger;

    public function __construct(TokenStorageInterface $tokenStorage, $secret, LoggerInterface $logger = null, AuthenticationManagerInterface $authenticationManager = null)
    {
        $this->tokenStorage = $tokenStorage;
        $this->secret = $secret;
        $this->authenticationManager = $authenticationManager;
        $this->logger = $logger;
    }

    public function handle(GetResponseEvent $event)
    {
        if (null !== $this->tokenStorage->getToken()) {
            return;
        }

        try {
            // This is the important line:
            $token = new AnonymousToken($this->secret, new AnonymousUser(), array());
            if (null !== $this->authenticationManager) {
                $token = $this->authenticationManager->authenticate($token);
            }

            $this->tokenStorage->setToken($token);

            if (null !== $this->logger) {
                $this->logger->info('Populated the TokenStorage with an anonymous Token.');
            }
        } catch (AuthenticationException $failed) {
            if (null !== $this->logger) {
                $this->logger->info('Anonymous authentication failed.', array('exception' => $failed));
            }
        }
    }
}

此文件是Symfony附带的AnonymousAuthenticationListener的副本,但更改了AnonymousToken构造函数以传递AnonymousUser类而不是字符串。就我而言,AnonymousUser是一个扩展我的User对象的类,但您可以随意实现它。

这些更改意味着Twig中的{{ app.user }}和PHP中的UserInterface注入将始终返回User:您可以使用isinstance来判断它是否为AnonymousUser,或向您的isLoggedIn类添加方法User,该true类在User中返回false,但在AnonymousUser中返回<input type="hidden" th:field="*{resetPasswordToken}" />。< / p>

答案 2 :(得分:0)

您可以重定向未经过身份验证的用户并强制进行虚假登录(以创建用户ANONYMOUS)

并在退出时设置它

public function logoutAction(){

    $em = $this->getDoctrine()->getManager();
    $user = $em->getRepository('VendorBundle:User')->findByUserName('annonymous');

    $session = $this->getRequest()->getSession();
    $session->set('user', $user);
}

如果未设置用户

public function checkLoginAction(){
    if(!$session->get('user')){
         $em = $this->getDoctrine()->getManager();
         $user = $em->getRepository('VendorBundle:User')->findByUserName('annonymous');
         $session = $this->getRequest()->getSession();
         $session->set('user', $user);
    }
    //this->redirect('/');
}

你的security.yml

security:
    firewalls:           
        main:
            access_denied_url: /check_login/

access_control:
        - { path: ^/$, role: ROLE_USER }

这只是我没有测试的一个例子(并且可能不会,因为我没有达到这样做的目的:))

答案 3 :(得分:0)

使用Symfony 2.6

像Gordon所说,使用身份验证侦听器来覆盖默认的匿名用户。 现在,您可以将所需的属性添加到匿名用户,在我的情况下是语言和货币。

security.yml

parameters:
    security.authentication.listener.anonymous.class: AppBundle\Security\Http\Firewall\AnonymousAuthenticationListener

AnonymousAuthenticationListener.php

namespace AppBundle\Security\Http\Firewall;

...
use AppBundle\Security\User\AnonymousUser;

class AnonymousAuthenticationListener implements ListenerInterface
{
    ...

    public function handle(GetResponseEvent $event)
    {
        ...

        try {
            $token = new AnonymousToken($this->key, new AnonymousUser(), array());
            ...
        }
    }
}

AnonymousUser.php

class AnonymousUser implements UserInterface
{
    public function getUsername() { return 'anon.'; }
}