How to log users off automatically after a period of inactivity?

后端 未结 9 1793
心在旅途
心在旅途 2020-11-27 03:21

After a lot of search in the web and find nothing, I wonder if there is an easy way to automatic logout the user logged through the Symfony Security after an inactive period

相关标签:
9条回答
  • 2020-11-27 03:41

    What about:

    #app/config/config.yml
    framework:
        session:
            cookie_lifetime:       1800
    
    0 讨论(0)
  • 2020-11-27 03:46

    Works perfect with FOSUserbundle, thank you.

    I added this to the inner condition to prevent the anonymous user to get logged out.

    ...
    
    $isFullyAuthenticated = $this->securityContext->isGranted('IS_AUTHENTICATED_FULLY');
    
    if ($lapse > $this->maxIdleTime && $isFullyAuthenticated == true) {
    
     ... do logout / redirect etc.
    
    }
    
    0 讨论(0)
  • 2020-11-27 03:47

    In case anybody wants to implement this in Symfony 4, I've updated the answer @coma gave since security.context is depreciated, parameters.yml is now just part of app/config/service.yaml and you can just inject the other variables for the contructor. It's basically the same answer though, just tweaked to work for Symfony 4:

    Listener src/Security/SessionIdleHandler.php (or anywhere, it's mapped in the event listener below)

    <?php
    
    namespace App\Security;
    
    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($maxIdleTime, SessionInterface $session, TokenStorageInterface $securityToken, RouterInterface $router)
        {
            $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.');
    
                    // logout is defined in security.yaml.  See 'Logging Out' section here:
                    // https://symfony.com/doc/4.1/security.html
                    $event->setResponse(new RedirectResponse($this->router->generate(logout)));
                }
            }
        }
    }
    

    Parameters app/config/service.yaml

    parameters:
        ...
        session_max_idle_time: 600 // set to whatever value you want in seconds
    

    Kernel Event Listener app/config/service.yaml

    services:
        ...
        App.Handler.SessionIdle:
            class: App\Security\SessionIdleHandler
            arguments: ['%session_max_idle_time%']
            tags: [{ name: kernel.event_listener, event: kernel.request }]
    
    0 讨论(0)
  • 2020-11-27 03:57

    cookie lifetime is not appropriate because that can be manipulated by the client, so we must do the expiry on the server side. The easiest way is to implement this via garbage collection which runs reasonably frequently. The cookie_lifetime would be set to a relatively high value, and the garbage collection gc_maxlifetime would be set to destroy sessions at whatever the desired idle period is.

    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
    
    0 讨论(0)
  • 2020-11-27 03:59

    A simple redirection to logout after moment using twig in your layout

    First create your twig extension

    #App/Twig/LogoutAfterMomentExtension.php  
    
    <?php
    
    
    namespace App\Twig;
    
    use Twig\Extension\AbstractExtension;
    use Twig\TwigFunction;
    
    class LogoutAfterMomentExtension extends AbstractExtension
    {
        public function getFunctions()
        {
            return [
                new TwigFunction('logoutAfter', [$this, 'logoutAfter']),
            ];
        }
    
        public function logoutAfter(int $seconds)
        {
            return header( "refresh:".$seconds.";url=/admin/logout" );
        }
    
    }
    

    call the function in the template

    #templates/layout.html.twig
    
    <body>
    
    {{ logoutAfter(5) }} #it will logout after 5 seconds
    ...
    
    </body>
    
    0 讨论(0)
  • 2020-11-27 04:01

    In Symfony 2.4, the following worked just fine for me for a 1 hour time out :

    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:   ~
    
    0 讨论(0)
提交回复
热议问题