簡體   English   中英

symfony中的匿名用戶對象

[英]Anonymous user object in symfony

我使用的是Symfony提供的基本用戶登錄/注銷系統,只要人們登錄它就可以正常工作。在這種情況下,始終根據需要提供$ user對象。

問題是,當注銷(或尚未登錄)時,沒有用戶對象。 (在那種情況下)是否有可能提供一個帶有我自己的默認值的默認用戶對象?

謝謝你的建議

因為@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。 因此,仍然歡迎更好的建議。

在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類中,該類在User中返回true ,但是在AnonymousUser false

您可以重定向未經身份驗證的用戶並強制進行假登錄(以創建匿名用戶)

並在注銷時進行設置

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 }

這只是我未測試過的一個示例(可能不會,因為我沒有達到此目的:))

使用Symfony 2.6

就像戈登所說的那樣,使用身份驗證偵聽器覆蓋默認的匿名用戶。 現在,您可以將所需的屬性添加到匿名用戶(在我的情況下為語言和貨幣)。

安全性

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM