如何在一段时间不活动后自动closures用户?

在网上search了很多东西之后,我发现有一个简单的方法可以在非活动时间之后自动注销通过Symfony Securitylogin的用户。 例如,我希望用户在闲置30分钟后注销。

我使用这样的自定义用户提供程序。

但在用户login系统后,会话永不过期。 即使closures浏览器并在几天之后再次打开,会话仍然有效。

无论如何,以自动方式甚至手动方式注销这个用户? 我怎样才能做到这一点?

你必须用一个内核监听器来实现它,这是我解决这个问题的方法:

Listener src / Comakai / MyBundle / Handler / SessionIdleHandler.php

namespace Comakai\MyBundle\Handler; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; class SessionIdleHandler { protected $session; protected $securityToken; protected $router; protected $maxIdleTime; public function __construct(SessionInterface $session, TokenStorageInterface $securityToken, RouterInterface $router, $maxIdleTime = 0) { $this->session = $session; $this->securityToken = $securityToken; $this->router = $router; $this->maxIdleTime = $maxIdleTime; } public function onKernelRequest(GetResponseEvent $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) { $this->securityToken->setToken(null); $this->session->getFlashBag()->set('info', 'You have been logged out due to inactivity.'); // Change the route if you are not using FOSUserBundle. $event->setResponse(new RedirectResponse($this->router->generate('fos_user_security_login'))); } } } } 

Config src / Comakai / MyBundle / Resources / config / services.yml(Comakai / MyBundle / DependencyInjection / MyBundleExtension.php)

 services: my.handler.session_idle: class: Comakai\MyBundle\Handler\SessionIdleHandler arguments: ["@session", "@security.context", "@router", %session_max_idle_time%] tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 

现在,您可以将参数 session_max_idle_time中的session_max_idle_time设置为30 * 60 = 1800秒(或者只需要硬编码值就可以):

参数 app / config / parameters.yml

 parameters: ... session_max_idle_time: 1800 

以下设置将注销超过30分钟不活动的用户。 如果每29分钟发一个请求,它们将不会被注销。 请注意,这在本地环境中testing并不容易,因为垃圾收集器只能从您的请求中调用,因此gc_maxlifetime永远不会到达!

 #app/config/config.yml session: cookie_lifetime: 86400 gc_maxlifetime: 1800 

如果您打开更多浏览器/会话并使用以下configuration,则可以testing此操作:

 #app/config/config.yml session: cookie_lifetime: 86400 gc_maxlifetime: 1800 gc_probability: 1 gc_divisor: 1 

希望有所帮助!

请注意,添加:

  session: gc_probability: 1 gc_divisor: 1 

仅用于在本地环境testing垃圾回收器,其中没有其他请求导致垃圾回收器删除会话。 让垃圾收集器在每个请求上运行并不意味着(或者必要)在一个高效的环境中!

与FOSUserbundle完美搭配,谢谢。

我将其添加到内部条件以防止匿名用户注销。

 ... $isFullyAuthenticated = $this->securityContext->isGranted('IS_AUTHENTICATED_FULLY'); if ($lapse > $this->maxIdleTime && $isFullyAuthenticated == true) { ... do logout / redirect etc. } 

在Symfony 2.4中,下面的工作对我来说只是1小时超时:

 framework: #esi: ~ translator: { fallback: %locale% } secret: %secret% router: resource: "%kernel.root_dir%/config/routing.yml" strict_requirements: ~ http_port: 80 https_port: 443 form: ~ csrf_protection: ~ validation: { enable_annotations: true } templating: engines: ['twig'] #assets_version: SomeVersionScheme default_locale: "%locale%" trusted_proxies: ~ session: cookie_lifetime: 3600 fragments: ~ trusted_hosts: ~ 

关于什么:

 #app/config/config.yml framework: session: cookie_lifetime: 1800 

cookie的生命周期是不合适的,因为这可以被客户端操纵,所以我们必须在服务器端执行到期。 最简单的方法是通过合理频繁运行的垃圾收集来实现这个function。 cookie_lifetime将被设置为相对较高的值,并且垃圾收集gc_maxlifetime将被设置为在任何期望的空闲时间内销毁会话。

 framework: #esi: ~ #translator: { fallback: "%locale%" } secret: "%secret%" router: resource: "%kernel.root_dir%/config/routing.yml" strict_requirements: ~ form: ~ csrf_protection: ~ validation: { enable_annotations: true } templating: engines: ['twig'] #assets_version: SomeVersionScheme default_locale: "%locale%" trusted_hosts: ~ trusted_proxies: ~ session: # handler_id set to null will use default session handler from php.ini #handler_id: ~ cookie_lifetime: 9999 gc_maxlifetime: 900 gc_probability: 1 gc_divisor: 2 fragments: ~ http_method_override: true