Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在Symfony中强制注销用户?_Php_Symfony_Authentication - Fatal编程技术网

Php 如何在Symfony中强制注销用户?

Php 如何在Symfony中强制注销用户?,php,symfony,authentication,Php,Symfony,Authentication,我有一个用户实体,它有一个布尔列被激活。根据每个用户的列值,他可能登录,也可能无法登录(即,他尚未激活帐户,因此无法登录)。我通过在防火墙中分配一个simple\u form.authenticator来实现这一点,它会在每次登录时进行检查 我正在试图弄清楚如何在用户仍在登录时强制注销 考虑下面的场景: 用户在其帐户仍处于活动状态时登录 管理员将停用用户的帐户 用户已注销,因为它不再处于活动状态 不幸的是,第三步没有发生。原因可能在于用户已经收到令牌,并且被Symfony 2.5的防火墙视为“被

我有一个
用户
实体,它有一个布尔列
被激活
。根据每个用户的列值,他可能登录,也可能无法登录(即,他尚未激活帐户,因此无法登录)。我通过在防火墙中分配一个
simple\u form.authenticator
来实现这一点,它会在每次登录时进行检查

我正在试图弄清楚如何在用户仍在登录时强制注销
考虑下面的场景:

  • 用户在其帐户仍处于活动状态时登录
  • 管理员将停用用户的帐户
  • 用户已注销,因为它不再处于活动状态
  • 不幸的是,第三步没有发生。原因可能在于用户已经收到令牌,并且被
    Symfony 2.5
    的防火墙视为“被破坏”(令牌可能缓存在安全上下文中?)


    我想知道克服这个问题的最好方法是什么?我应该编写一个内核事件侦听器还是一个?

    您可以通过以下两行终止用户的会话(如果您有权访问容器,否则您必须注入
    安全性。上下文和
    会话
    ):

    namespace Acme\MyBundle\Events;
    
    use Acme\MyBundle\Entity\User;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
    use Symfony\Component\Security\Core\SecurityContext;
    
    class RequestEvent {
    
        /**
         * @var \Symfony\Component\Security\Core\SecurityContext
         */
        private $securityContext;
    
        public function __construct(SecurityContext $context){
            $this->securityContext = $context;
        }
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            // not sure if this is actually needed?
            if (!$event->isMasterRequest()) {
                // don't do anything if it's not the master request
                return;
            }
    
            // try to get security context and catch the exception in case no firewall was configured (i.e. for the dev tool bar)
            try{
                // trigger only for logged in users
                if($this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')){
                    $token = $this->securityContext->getToken();
                    /**
                     * @var User $user
                     */
                    $user = $token->getUser();
                    if($user != null && !$user->isActive()){
                        $this->securityContext->setToken(null);
                    }
                }
            } catch(AuthenticationCredentialsNotFoundException $e){
                // don't do anything here... or do whatever you want.
            }
        }
    }
    
    ?>
    
    之后,用户应该注销


    如果您以前加载过用户实体,您可能也想取消设置。

    虽然@lxg回答了我的问题,但我决定扩展他的答案,以便其他有相同问题的人更好地了解如何解决该问题

    创建事件侦听器
    namespace Acme\MyBundle\Events;
    
    use Acme\MyBundle\Entity\User;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
    use Symfony\Component\Security\Core\SecurityContext;
    
    class RequestEvent {
    
        /**
         * @var \Symfony\Component\Security\Core\SecurityContext
         */
        private $securityContext;
    
        public function __construct(SecurityContext $context){
            $this->securityContext = $context;
        }
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            // not sure if this is actually needed?
            if (!$event->isMasterRequest()) {
                // don't do anything if it's not the master request
                return;
            }
    
            // try to get security context and catch the exception in case no firewall was configured (i.e. for the dev tool bar)
            try{
                // trigger only for logged in users
                if($this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')){
                    $token = $this->securityContext->getToken();
                    /**
                     * @var User $user
                     */
                    $user = $token->getUser();
                    if($user != null && !$user->isActive()){
                        $this->securityContext->setToken(null);
                    }
                }
            } catch(AuthenticationCredentialsNotFoundException $e){
                // don't do anything here... or do whatever you want.
            }
        }
    }
    
    ?>
    
    现在在您的
    service.yml
    中添加以下内容:

    services:
        kernel.listener.request_listener:
            class: Acme\MyBundle\Events\RequestEvent
            arguments: [ @security.context ]
            tags:
                - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
    

    一旦用户被停用,他将被强制重定向到防火墙的登录页面。希望这对某人有所帮助。

    symfony 3.4:
    $this->get('security.token\u storage')->setToken(null)$此->获取('session')->无效()
    在Symfony 3.4中,不应注入容器,而应使用自动布线。