【问题标题】:How can one force logout a user in Symfony?如何在 Symfony 中强制注销用户?
【发布时间】:2014-11-12 03:52:58
【问题描述】:

我有一个User 实体,它有一个布尔列isActivated。根据每个用户的列值,他可能能够登录,也可能无法登录(即他没有激活他的帐户,所以没有登录)。我通过在防火墙中分配一个simple_form.authenticator 来实现这一点,它会检​​查每次登录。

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

  1. 用户在其帐户仍处于活动状态时登录。
  2. 管理员停用了用户的帐户。
  3. 由于用户不再处于活动状态,因此用户已注销。

不幸的是,第 3 步没有发生。原因可能在于用户已经收到了令牌,并被Symfony 2.5的防火墙认为是“tursted”(可能令牌缓存在安全上下文中?)。

我想知道解决这个问题的最佳方法是什么?我应该写一个内核事件监听器还是Custom User Provider

【问题讨论】:

    标签: php symfony authentication


    【解决方案1】:

    你可以用以下两行终止用户的会话(如果你可以访问容器,否则你必须注入security.contextsession):

    $container->get('security.context')->setToken(null);
    $container->get('session')->invalidate();
    

    之后,用户应该被注销。

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

    【讨论】:

    • symfony 3.4:$this->get('security.token_storage')->setToken(null); $this->get('session')->invalidate();
    • 在 Symfony 3.4 中你不应该注入容器,而是使用自动连接。
    【解决方案2】:

    虽然@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 }
    

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

    【讨论】:

      猜你喜欢
      • 2022-08-08
      • 1970-01-01
      • 2019-03-31
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 2019-08-02
      • 1970-01-01
      • 2019-04-30
      相关资源
      最近更新 更多