Skip to content

Session invalidate prevents flashbag functionality and invalidate() is not the same as clear() then migrate() #5487

Closed
@adam-lynch

Description

@adam-lynch

I added a request listener (kernel event for every request) which does some session handling. Latest version of my code:

namespace ...

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Bridge\Monolog\Logger;

class RequestListener
{

    public $session;
    public $logger;

    public function __construct( Session $session, Logger $logger ) {
        $this->session = $session;
        $this->logger  = $logger;
        //leave blank
    }

    public function onKernelRequest( GetResponseEvent $event ) {

        if ( HttpKernel::MASTER_REQUEST != $event->getRequestType() ) {
            // don't do anything if it's not the master request
            return;
        }
        else {

            $session      = $this->session;
            $logger       = $this->logger;
            $current_time = time();

            //if they're logged in and it hasn't been more than X seconds since their last request
            if ( $session->get( 'auth' ) ) {
                $last_seen = (int) $session->get( 'last_seen' );
                if ( $last_seen > ( $current_time - 10 ) ) { //timeout: half hour
                    //regenerate session ID:
                    $session->migrate();
                    $logger->info( "Regenerating session ID, last_seen=" . $last_seen );
                }
                else {
                    //destroy session
                    $session->clear();
                    $session->migrate();
                    //$session->invalidate(); //shortcut for clear() & then migrate()

                    //set session variable to acknowledge timeout
                    $session->setFlash( 'error', 'You were automatically logged out due to inactivity' ); 

                    $logger->info( "Session timeout (upon request from returning user)" );

                }
                $session->set( 'last_seen', $current_time );
            }
            else {
                $session->set( 'last_seen', $current_time );
            }
        }
    }
}

On every request, the last_seen session variable is updated to the current time ( time() ). If the last_seen is more than X seconds ago, then I clear the session, regenerate the session ID, and update last_seen as normal.

For usability, I wanted to add a session timeout message to the flashbag because some pages will redirect to the login page if the user isn't authenticated (where the flash message would be displayed). (FYI, I used the deprecated setFlash here while debugging the problem)

When $session->invalidate() is used, the flash message is no longer there when the login page renders the template. When clear() and then migrate() is used, it is.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions