如何使用它的内部处理程序将用户从 Symfony 2 应用程序中注销
Posted
技术标签:
【中文标题】如何使用它的内部处理程序将用户从 Symfony 2 应用程序中注销【英文标题】:How to log user out of Symfony 2 application using it's internal handlers 【发布时间】:2015-05-03 21:42:30 【问题描述】:Symfony 实现了注销用户和终止 cookie 的功能。有一个 LogoutListener
将这些操作委托给几个注销处理程序:CookieClearingLogoutHandler
和 SessionLogoutHandler
。
如果我们想手动将用户从应用程序中注销,我认为最好的做法是调用这些处理程序,而不是自己实现(复制)这种低级逻辑。
可以吗?
【问题讨论】:
【参考方案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 向此侦听器注入一些额外的服务?或者更好的方法是先使用其他监听器来设置会话变量?
我想我会用我自己的覆盖整个服务定义并注入所需的服务。感谢您的宝贵时间!
嗯,由于某种原因,在防火墙内核事件侦听器完成之前我无法访问当前用户,我需要注销侦听器中的用户来决定是否需要将他注销或不是。有可能对此做些什么吗?以上是关于如何使用它的内部处理程序将用户从 Symfony 2 应用程序中注销的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Symfony 2.1 从内部控制器获取 Doctrine 实体的实体管理器