如果没有一些不必要的 Symfony 黑客攻击,您正在谈论的功能(防止更新会话 lastUsed)就无法完成,因为您可以为此简单地创建自己的逻辑。例如,您可以创建KernelRequest listener,它将更新所有请求的最后使用的会话变量,除了您将用于检查还剩多少时间的注销:
public function onKernelRequest(GetResponseEvent $event): void
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
//$this->sessionMaxIdleTime is number from config parameter
//representing max idle time in seconds
if ($this->sessionMaxIdleTime > 0) {
$this->session->start();
$time = time();
$route = $event->getRequest()->attributes->get('_route');
//for all routes but one - checking how much time is left
if ('session_check' !== $route) {
//manual set lastUsed time
$this->session->set('manualLastUsedTime', $time);
}
$idleTime = $time - $this->session->get('manualLastUsedTime');
if ($idleTime > $this->sessionMaxIdleTime) {
$this->session->invalidate();
$this->session->getFlashBag()->set('info', 'Logged out due to inactivity.');
if ($event->getRequest()->isXmlHttpRequest()) {
$event->setResponse(new Response('Logged out due to inactivity.', Response::HTTP_FORBIDDEN));
} else {
$event->setResponse(new RedirectResponse($this->router->generate('login')));
}
}
}
然后您可以在某个控制器中简单地创建方法,该方法将被某些 ajax 函数用于检查还剩多少时间退出,例如:
/**
* @Route("/session/check", name="session_check", methods={"GET"})
* @param Request $request
* @param SessionInterface $session
* @param int $sessionMaxIdleTime
* @return JsonResponse
*/
public function checkSecondsToExpire(Request $request, SessionInterface $session, $sessionMaxIdleTime = 0): JsonResponse
{
$idleTime = time() - $session->get('manualLastUsedTime');
$secToExp = $sessionMaxIdleTime - $idleTime;
return new JsonResponse(['secToExp' => $secToExp]);
}
最后一点是做一些检查机制。它可以像在基本模板中启动一些 JS 函数一样简单。参数为twig语法,来自config(与kernelRequest监听器中的sessionMaxIdleTime相同):
<script>
$(document).ready(function () {
SessionIdler.start({{ session_max_idle_time }});
});
</script>
SessionIdler.start 只是一个在特定时间间隔内运行其他函数的函数(在本例中,它将在配置 sessionmaxIdleTime 之前运行 1 分钟):
function start(time) {
checkSessionCounter = setInterval(checkSession, (time - 60) * 1000);
isCheckSessionCounterRunning = true;
// console.debug("checkSession will START in: " + (time - 60) + "s");
}
checkSession 函数向我们的session_check 路由发出 ajax 请求,并取决于结果,它显示模式与关于太长时间不活动的正确信息。模态在隐藏时可以有一个按钮或一个动作,这将向session_extend路由发出另一个请求(它什么都不做——它只需要被kernelRequest监听器捕获以覆盖manualLastUsedTime)
这三个部分共同创建了一种机制,用于通知用户长时间不活动,而不会对会话 metadataBag 产生任何影响。