我正在使用SecurityServiceProvider来保护我的 Silex 应用程序,并希望在用户注销后通过导航到logout_path路由来显示一条消息。
该消息应该存储在会话闪存包中,以便我的模板可以在之后自动显示它。
我曾尝试添加一个应用程序中间件,但无法将我的代码挂钩。 before 挂钩似乎不起作用,因为它发生在安全之后,因此在安全重定向回我的主页之后。
Application::EARLY_EVENT的 before 钩子似乎为时过早,因为据我所知,安全提供程序在注销后会销毁会话。
在我继续尝试找到一种可行但可能很脏的解决方案之前,我想问一下这种情况下最好/最干净的解决方案是什么?
更新:在 npms 提示注销事件处理程序后,我在 Google 上找到了这篇文章,其中描述了如何很好地解决 Symfony 中的问题。
在 Silex 中,情况略有不同,在阅读了SecurityServiceProvider的源代码后,我想出了这个解决方案。
$app['security.authentication.logout_handler._proto'] = $app->protect(function ($name, $options) use ($app) {
return $app->share(function () use ($name, $options, $app) {
return new CustomLogoutSuccessHandler(
$app['security.http_utils'],
isset($options['target_url']) ? $options['target_url'] : '/'
);
});
});
class CustomLogoutSuccessHanler extends DefaultLogoutSuccessHandler {
public function onLogoutSuccess(Request $request)
{
$request->getSession()->getFlashBag()->add('info', "Logout success!");
return $this->httpUtils->createRedirectResponse($request, $this->targetUrl);
}
}
然而,问题是,在重定向后 flashbag 消息不再存在。因此,执行注销成功处理程序后似乎会话正在被破坏......或者我错过了什么?这甚至是正确的方法吗?
更新:还没有找到合适的解决方案。但这有效。
我在注销的目标 url 中添加了一个参数,并使用它来检测是否进行了注销。
$app->register( new SecurityServiceProvider(), array(
'security.firewalls' => array(
'default' => array(
'pattern'=> '/user',
'logout' => array(
'logout_path' => '/user/logout',
'target_url' => '/?logout'
),
)
)
));