简体   繁体   English

symfony中的匿名用户对象

[英]Anonymous user object in symfony

I'm using the basic user login/logout system provided with Symfony and it works fine as long as people log in. In that case the $user object is always provided as needed. 我使用的是Symfony提供的基本用户登录/注销系统,只要人们登录它就可以正常工作。在这种情况下,始终根据需要提供$ user对象。

The problem is then when logged out (or not lgged in yet) there is no user object. 问题是,当注销(或尚未登录)时,没有用户对象。 Is there a possibility to have (in that case) a default user object provided with my own default values? (在那种情况下)是否有可能提供一个带有我自己的默认值的默认用户对象?

Thanks for your suggestions 谢谢你的建议

Because the solution mention above by @Chopchop (thanks anyway for your effort) didn't work here I wrote a little workaround. 因为@Chopchop上面提到的解决方案(无论如何都要感谢您的努力)在这里不起作用,所以我写了一些解决方法。

I created a new class called myController which extends Controller. 我创建了一个名为myController的新类,该类扩展了Controller。 The only function i override is the getUser() function. 我重写的唯一函数是getUser()函数。 There I implement it like this: 在那里,我这样实现:

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;
}

This works fine for me now. 现在对我来说这很好。 The only problem is that you really have to be careful NOT to forget to replace Controller by myController in all your *Controller.php files. 唯一的问题是,您真的要非常小心,不要忘记在所有* Controller.php文件中都用myController替换Controller。 So, better suggestions still welcome. 因此,仍然欢迎更好的建议。

Works in Symfony 3.3 在Symfony 3.3中工作

Using the suggestion of @Sfblaauw, I came up with a solution that uses a CompilerPass . 根据@Sfblaauw的建议,我想出了一个使用CompilerPass的解决方案。

AppBundle/AppBundle.php AppBundle / AppBundle.php

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

OverrideAnonymousUserCompilerPass.php OverrideAnonymousUserCompilerPass.php

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

AnonymousAuthenticationListener.php 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));
            }
        }
    }
}

This file is a copy of the AnonymousAuthenticationListener that comes with Symfony, but with the AnonymousToken constructor changed to pass in an AnonymousUser class instead of a string. 该文件是Symfony随附的AnonymousAuthenticationListener的副本,但AnonymousToken构造函数已更改为传递AnonymousUser类而不是字符串。 In my case, AnonymousUser is a class that extends my User object, but you can implement it however you like. 就我而言, AnonymousUser是扩展我的User对象的类,但是您可以根据需要实现它。

These changes mean that {{ app.user }} in Twig and UserInterface injections in PHP will always return a User : you can use isinstance to tell if it's an AnonymousUser , or add a method isLoggedIn to your User class which returns true in User but false in AnonymousUser . 这些更改意味着Twig中的{{ app.user }}和PHP中的UserInterface注入将始终返回一个User :您可以使用isinstance来判断它是否是AnonymousUser ,或者将isLoggedIn方法添加到User类中,该类在User中返回true ,但是在AnonymousUser false

you can redirect the user not authenticated and force a fake login (to create a user ANONYMOUS) 您可以重定向未经身份验证的用户并强制进行假登录(以创建匿名用户)

and set it as well on logout 并在注销时进行设置

public function logoutAction(){

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

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

and if user is not set 如果没有设置用户

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('/');
}

in you security.yml 在您的security.yml中

security:
    firewalls:           
        main:
            access_denied_url: /check_login/

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

This is only an example i haven't tested (and will probably don't, since i don't get the purpose of doing this:) ) 这只是我未测试过的一个示例(可能不会,因为我没有达到此目的:))

Using Symfony 2.6 使用Symfony 2.6

Like Gordon says use the authentication listener to override the default anonymous user. 就像戈登所说的那样,使用身份验证侦听器覆盖默认的匿名用户。 Now you can add the properties that you need to the anonymous user, in my case the language and the currency. 现在,您可以将所需的属性添加到匿名用户(在我的情况下为语言和货币)。

security.yml 安全性

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

AnonymousAuthenticationListener.php 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 AnonymousUser.php

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

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

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