Question

I'm in a (unique?) situation where I want people who are logged in to stay logged in as long as possible. Ideally, a month (marketing wanted a year). We are storing session data in a database rather then the default file.

We don't store any personal information or anything else that would be a security risk.

The problem I'm running into is that I don't want to accumulate tons of session data in a table and have that affect server latency. In order to do that, I'd like to store somebody's session for 86400 seconds (1day) when they're on anonymously, but change that to 2592000 seconds (30 days) once they've logged in.

I'm using zend framework 1.12 and have my application.ini as follows:

resources.session.gc_maxlifetime = 86400
resources.session.remember_me_seconds = 2592000
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable"
resources.session.saveHandler.options.name = "session"
resources.session.saveHandler.options.primary[] = "session_id"
resources.session.saveHandler.options.primary[] = "save_path"
resources.session.saveHandler.options.primary[] = "name"
resources.session.saveHandler.options.primaryAssignment[] = "sessionId"
resources.session.saveHandler.options.primaryAssignment[] = "sessionSavePath"
resources.session.saveHandler.options.primaryAssignment[] = "sessionName"
resources.session.saveHandler.options.modifiedColumn = "modified"
resources.session.saveHandler.options.dataColumn = "session_data"
resources.session.saveHandler.options.lifetimeColumn = "lifetime"

When I first come to the site the lifetime is set as "86400", but once I login it doesn't change. I assume that remember_me is different than garbage collection, and that my month-long remember_me is pointless, since its going to be collected after a day thus destroying the session, anyway. So, I tried Modifying it when I login. Here's my login logic:

    $adapter = new Activejunky_Auth_Adapter_Doctrine($values['username'], $values['password']);
    $auth = Zend_Auth::getInstance();
    $sessionOptions = array(
        'gc_maxlifetime'            => 2592000,
        'remember_me_seconds'   => 2592000,
    );
    Zend_Session::setOptions($sessionOptions);
    Zend_Session::rememberMe(60 * 60 * 24 * 30);
    error_log('you working?');
    Zend_Session::start();

    $result = $auth->authenticate($adapter);

    if ( $result->isValid() )
    {
        $user = $adapter->getResultObject();
        $user->last_login = time();
        $user->save();

        //STORE USER INFO
        $authStorage = $auth->getStorage();
        $authStorage->write($user->toArray());

That, However, still doesn't work. I'm logged in alright, but the lifetime is still set to 86400. Is there anyway to do this? or am I nuts for even trying?

EDIT

So its easier to read, here's what I did. on the page after they're logged in:

            $aj = new Zend_Session_Namespace('aj');
            if($aj->lifetime == 'day')
        {
            $db = Zend_Db_Table::getDefaultAdapter();
            $sid = Zend_Session::getId();
            $where = $db->quoteInto('session_id = ?', Zend_Session::getId());
            $db->update('session', array('lifetime' => 2592000), $where);
            $aj->lifetime = 'month';
        }

AND Here's my application.ini:

resources.session.gc_maxlifetime = 7200
resources.session.remember_me_seconds = 2592000
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable"
resources.session.saveHandler.options.name = "session"
resources.session.saveHandler.options.primary[] = "session_id"
resources.session.saveHandler.options.primary[] = "save_path"
resources.session.saveHandler.options.primary[] = "name"
resources.session.saveHandler.options.primaryAssignment[] = "sessionId"
resources.session.saveHandler.options.primaryAssignment[] = "sessionSavePath"
resources.session.saveHandler.options.primaryAssignment[] = "sessionName"
resources.session.saveHandler.options.modifiedColumn = "modified"
resources.session.saveHandler.options.dataColumn = "session_data"
resources.session.saveHandler.options.lifetimeColumn = "lifetime"
resources.view.doctype = "HTML5"
resources.view.language = "en"
Was it helpful?

Solution

For database backed-sessions, you can specifically control the behavior of session deletion. gc_max_lifetime is simply a parameter that is passed to your gc() session handler function. It can be used or ignored as you like. You just need to use whatever logic you desire.

For example, you could simply add a field to the database to determine if this is a "long" session or a "short session". Then change your DELETE SQL accordingly. So something like this:

DELETE FROM sessions
WHERE
    (long_session = 1 AND timestamp_field < DATE_SUB(NOW(), INTERVAL 30 DAYS)) OR
    (long_session = 0 AND timestamp_filed < DATE_SUB(NOW(), INTERVAL 1 DAY))

Here you could use INTERVAL X SECONDS as well if you want to use the gc_max_lifetime value as passed to gc().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top