【问题标题】:How to log user out of Symfony 2 application using it's internal handlers如何使用它的内部处理程序将用户从 Symfony 2 应用程序中注销
【发布时间】:2015-05-03 21:42:30
【问题描述】:

Symfony 实现了注销用户和终止 cookie 的功能。有一个 LogoutListener 将这些操作委托给几个注销处理程序:CookieClearingLogoutHandlerSessionLogoutHandler

如果我们想手动将用户从应用程序中注销,我认为最好的做法是调用这些处理程序,而不是自己实现(复制)这种低级逻辑。

可以吗?

【问题讨论】:

    标签: php security symfony logout


    【解决方案1】:

    您可以通过覆盖默认的security.logout_listener 服务来实现扩展的注销侦听器。

    默认的LogoutListener::requiresLogin(...) 方法只检查请求路径是否等于防火墙的logout_path 设置。

    看起来像这样:

    protected function requiresLogout(Request $request)
    {
        return $this->httpUtils->checkRequestPath(
            $request, $this->options['logout_path']
        );
    }
    

    现在让我们假设如果会话参数 logout 设置为 true,您想要执行注销。

    因此,我们扩展 LogoutListener 类并添加我们的自定义 requiresLogout() 方法和额外的逻辑。

    namespace Your\Name\Space;
    
    use Symfony\Component\Security\Http\Firewall\LogoutListener;
    use Symfony\Component\HttpFoundation\Session\SessionInterface;
    
    class MyLogoutListener extends LogoutListener {
    
        /**
         * Whether this request is asking for logout.
         *
         * @param Request $request
         *
         * @return Boolean
         */ 
        protected function requiresLogout(Request $request)
        {
            if ( $request->getSession()->get('logout') ) {
                return true;
            }
    
            return parent::requiresLogout($request);
        }
    

    之后,我们只需使用 config.yml 中的自定义类覆盖security.logout_listener.class 容器参数。

    parameters:
        security.logout_listener.class: \Your\Name\Space\MyLogoutListener
    

    现在您可以像这样在...Controller 中注销用户:

     public function someAction(Request $request) { 
    
         // ... some logic here
    
         if ($condition) {      
             $request->getSession()->set('logout', true);
         }
     }
    

    【讨论】:

    • 一个非常优雅的解决方案!谢谢,我试试看。
    • 我没有时间测试,但它绝对应该像这样工作。这是您期望的问题答案吗?
    • 我的用户实体中有一个属性,说明是否需要踢出特定用户。我可以这样查询:$user->isForceLogout()。但是,是否可以让当前用户进入此侦听器?我试过$request->getUser(),但似乎它总是返回NULL。另外,是否可以通过 setter 向此侦听器注入一些额外的服务?或者更好的方法是先使用其他监听器来设置会话变量?
    • 我想我会用我自己的覆盖整个服务定义并注入所需的服务。感谢您的宝贵时间!
    • 嗯,由于某种原因,在防火墙内核事件侦听器完成之前我无法访问当前用户,我需要注销侦听器中的用户来决定是否需要将他注销或不是。有可能对此做些什么吗?
    猜你喜欢
    • 2021-10-21
    • 2015-05-03
    • 2011-09-19
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 2017-11-07
    相关资源
    最近更新 更多