Events 通过Silex SecurityServiceProvider注销后显示消息

Events 通过Silex SecurityServiceProvider注销后显示消息,events,silex,Events,Silex,我正在使用SecurityServiceProvider保护我的Silex应用程序,并希望在用户通过导航到注销路径注销后显示一条消息 该消息应存储在会话闪存包中,以便我的模板可以在会话后自动显示它 我曾尝试添加一个应用程序中间件,但无法将代码挂接到其中。before钩子似乎不起作用,因为它发生在安全性之后,因此在安全性重定向回我的主页之后 带有应用程序::EARLY_事件的before钩子似乎太早了,因为据我所知,安全提供程序在注销后是否会破坏会话 在我继续尝试寻找一种有效但可能不干净的解决方案

我正在使用SecurityServiceProvider保护我的Silex应用程序,并希望在用户通过导航到注销路径注销后显示一条消息

该消息应存储在会话闪存包中,以便我的模板可以在会话后自动显示它

我曾尝试添加一个应用程序中间件,但无法将代码挂接到其中。before钩子似乎不起作用,因为它发生在安全性之后,因此在安全性重定向回我的主页之后

带有应用程序::EARLY_事件的before钩子似乎太早了,因为据我所知,安全提供程序在注销后是否会破坏会话

在我继续尝试寻找一种有效但可能不干净的解决方案之前,我想问一下,对于这种情况,最好/最干净的解决方案是什么

更新:在npms提示之后,我在Google上找到了一个注销事件处理程序,它很好地描述了如何在Symfony中解决这个问题

但在Silex中,情况略有不同,在阅读SecurityServiceProvider的源代码后,我提出了这个解决方案

$app['security.authentication.logout\u handler.\u proto']=$app->protect(函数($name,$options)use($app){
返回$app->share(函数()使用($name、$options、$app){
返回新的CustomLogoutSuccessHandler(
$app['security.http_utils'],
isset($options['target\u url'])?$options['target\u url']:'/'
);
});
});
类CustomLogoutSuccessHandler扩展了DefaultLogoutSuccessHandler{
公共函数onLogoutSuccess(请求$Request)
{
$request->getSession()->getFlashBag()->add('info',“注销成功!”);
返回$this->httpUtils->createRedirectResponse($request,$this->targetUrl);
}
}
但问题是,在重定向之后,flashbag消息不再存在。因此,在执行注销成功处理程序后,会话似乎正在被销毁。。。还是我遗漏了什么?这样做对吗

更新:仍然没有找到合适的解决方案。但这是可行的

我已经在注销的目标url中添加了一个参数,并使用它来检测是否进行了注销

$app->register(新SecurityServiceProvider(),数组(
“安全性.防火墙”=>阵列(
'默认'=>数组(
'模式'=>'/user',
“注销”=>数组(
“注销路径”=>“/user/logout”,
'目标url'=>'/?注销'
),
)
)
));

我也遇到了同样的问题,您的想法引导我找到了解决方案,谢谢

首先在安全防火墙中定义注销:

$app->register(新的Silex\Provider\SecurityServiceProvider(),数组(
“安全性.防火墙”=>阵列(
“常规”=>数组(
“注销”=>数组(
“注销路径”=>“/admin/logout”,
'目标url'=>'/再见'
)
)
),
));
创建一个CustomLogoutSuccessHandler,用于处理注销所需的获取参数,在本例中为重定向消息pid

类CustomLogoutSuccessHandler扩展了DefaultLogoutSuccessHandler
{
公共函数onLogoutSuccess(请求$Request)
{
//使用另一个目标?
$target=$request->query->get('redirect',$this->targetUrl);
$parameter=array();
如果(null!=($pid=$request->query->get('pid')){
$parameter['pid']=$pid;
}
if(null!=($message=$request->query->get('message')){
$parameter['message']=$message;
}
$parameter_str=!empty($parameter)“?”。http_build_query($parameter):“”;
返回$this->httpUtils->createRedirectResponse($request,$target.$parameter\u str);
}
}
注册处理程序:

$app['security.authentication.logout\u handler.general']=$app->share(函数()使用($app){
返回新的CustomLogoutSuccessHandler(
$app['security.http_utils','/bye');
});
使其按预期工作的诀窍是使用另一条路径注销:

$app->get('/logout',function()使用($app){
$pid=$app['request']->query->get('pid');
$message=$app['request']->query->get('message');
$redirect=$app['request']->query->get('redirect');
返回$app->redirect(FRAMEWORK_URL./admin/logout?pid=$pid&message=$message&redirect=$redirect”);
});
/logout设置所需参数并执行定期注销/admin/logout

现在你可以使用

/logout?redirect=anywhere
注销后重定向到任何其他路由或

/logout?message=xyz

(已编码)以提示/bye对话框中的任何消息。

应该有一个事件,您可以在注销时监听以执行自定义侦听器。感谢您的提示。我已经更新了我的问题。我喜欢添加重定向参数的想法,我认为它很好地实现了您的方式。我没有得到的是自定义注销路径。难道你不能将参数添加到系统默认的注销路径吗?我曾尝试将参数直接添加到默认的注销路径,但它们没有传递到控制器,因此无法工作。使用另一个注销路径启用通过,因此我使用这种方式。