【问题标题】:Symfony 5 - Prevent user from logging out after timeSymfony 5 - 防止用户在一段时间后退出
【发布时间】:2021-01-12 09:58:44
【问题描述】:

根据文档:

在某些情况下您可能想要保护,或者 当用户离开时,最大限度地减少未经授权的会话使用 他们的终端在登录后通过销毁会话 一定的空闲时间。例如,银行业务很常见 应用程序在 5 到 10 分钟后注销用户 不活动。此处设置 cookie 生命周期是不合适的 因为这可以由客户端操纵,所以我们必须这样做 服务器端过期。最简单的方法是通过 合理频繁地运行的垃圾收集。这 cookie_lifetime 将被设置为一个相对较高的值

将 cookie_lifetime 设置为 0 将导致 cookie 仅在浏览器保持打开时才存在。

我没有搞砸垃圾收集器,但我尝试在会话配置中添加cookie_lifetime

framework.yaml

framework:
    session:
        cookie_lifetime: 0

没用。

我尝试过继承:

use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;

class MySessionTime extends NativeSessionStorage
{
    public function __construct()
    {
        parent::__construct(['cookie_lifetime' => "0"]);
    }
}

它没有帮助。 清除 Symfony 缓存也没有帮助。

我的用户每隔几分钟就会自动退出。 我希望我的应用程序让用户在会话处于活动状态时保持登录状态。

【问题讨论】:

  • 您尝试过什么检查为什么会发生这种情况?那个饼干能放多久?您为 PHP 会话配置了哪个生命周期?
  • 它与cookie无关,因为Symfony应该将这些信息存储在服务器端的会话中。然后垃圾收集器根据其配置清除该会话值。我将检查配置值(gc_probability、gc_divisor 和 gc_maxlifetime)。 If the garbage collection handler is invoked, PHP will pass the value stored in the php.ini directive session.gc_maxlifetime. The meaning in this context is that any stored session that was saved more than gc_maxlifetime ago should be deleted. This allows one to expire records based on idle time.
  • 请分享更多细节。是什么让您认为 PHP 会话可以在没有 cookie 的情况下以任何方式工作?
  • 真的吗? “会话”是“会话cookie”的快捷方式。 “Cookie”是客户端环境中常用的短语。 “会话”或“会话 cookie”是服务器端环境中常用的短语。你的意思是“会话”,但你说的是“cookie”。不是我的错。
  • “该 cookie 能持续多久”是一个与会话 cookie 相关的非常明确的问题,除非您刷新每个请求的生命周期,否则会话本身(服务器端)的生命周期也会受到影响。请不要对试图帮助你的人无礼

标签: symfony session


【解决方案1】:

我建议另一种方法。 如果没有请求,请创建一个服务并添加您希望在 X 分钟后断开用户连接的时间。

我会这样做:

class LogoutIfInactiveListener{

private SessionInterface $session;
private RouterInterface $router;
private TokenStorageInterface $token;
private int $maxIdleTime = 0;

public function __construct(SessionInterface $session, RouterInterface $router, TokenStorageInterface $token, int $maxIdleTime)
{
    $this->session = $session;
    $this->router = $router;
    $this->token = $token;
    $this->maxIdleTime = $maxIdleTime;
}

public function onKernelRequest(RequestEvent $event)
{
    if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) {
        return;
    }

    if ($this->maxIdleTime > 0) {

        $this->session->start();
        $lapse = time() - $this->session->getMetadataBag()->getLastUsed();

        if ($lapse > $this->maxIdleTime) {
            $event->setResponse(new RedirectResponse($this->router->generate('app_logout')));
        }
    }
}

别忘了在你的 service.yml 中使用它。更进一步你甚至可以在 JS 中使用 setTimeOut 来自动刷新页面

【讨论】:

  • 如果根本原因未知,这将无济于事
  • 这不会阻止 Symfony 检查完全相同的内容并注销用户。您的代码只检查您的空闲时间是否触发,然后 Symfony 垃圾收集器仍然在做自己的事情。如果我错了,请纠正我,但你的听众不会覆盖 Symfonys 的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多