Welcome, Guest. Register Now!
   
Mark Forums Read Mark Forums Read Mark Forums Read


Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 06-17-2008, 07:23 AM
Junior Member
 
Join Date: Jun 2008
Posts: 1
Default weird session timeout for user inactivity

Hi,
What I want to do is very general & simple. I am sure I am missing something.

I am authenticating & a suer & setting session in the following way :
PHP Code:
$authAdapter = new Zend_Auth_Adapter_DbTable($db);

    
$authAdapter->setTableName('users');

    
$authAdapter->setIdentityColumn('username');

    
$authAdapter->setCredentialColumn('password');

    
// Set the input credential values to authenticate against

    
$authAdapter->setIdentity($username);

    
$authAdapter->setCredential($password);

    
// do the authentication

    
$auth Zend_Auth::getInstance();

    
$result $auth->authenticate($authAdapter);

    if (
$result->isValid()) {

    
// success: store database row to auth's storage

    // system. (Not the password though!)

    
$data $authAdapter->getResultRowObject(null,

    
'password');

    
$auth->getStorage()->write($data);

        
$fullName Zend_Auth::getInstance()->getIdentity();

   

    
// Set session expiry

    
$authNamespace = new Zend_Session_Namespace('Zend_Auth');

    
$authNamespace->user $username;

    
$authNamespace->setExpirationSeconds(1200); 

Now what happens is that the user is authenticated & session is set but the session expires after 20 mins regardless of whether there was any inactivity or the user was actively working on the application.

What I need is that the session should expire only if there is an inactivity of 20mins, not just time lapse of 20 min. But as of now, even when I am actively clicking away on the app, I get logged out.
Please help. Also pls suggest any better way to do the above. I am sure I am not using the best methods available in this pool of ZF.

Thanks.
Mayank
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 06-27-2008, 06:01 PM
Junior Member
 
Join Date: Jun 2008
Location: Nevada
Posts: 2
Default A brute-force inactivity timeout

This method is rather brute-force, but it works reasonably well. First, in the bootstrap file, I started a session (this is a best practice anyway):

Code:
<?php
// ...

// Start up a session
require_once 'Zend/Session.php';
Zend_Session::start();

// ...
I created a LoginController.php separate from the other controllers. In that controller, I added this code (using a session namespace to track timeouts, as well as the user's current location):

Code:
<?php
// LoginController.php - Controls application login/logout

class LoginController extends Zend_Controller_Action
{
    // Application login function.  Runs under the URL http://app/Login/login.
    function loginAction()
    {
        // ... do the login stuff ...

        // .. at the point of a successful login ...
        if (Zend_Auth::getInstance()->hasIdentity()) {
            $authNamespace = new Zend_Session_Namespace('auth');
            // timeout is 20 minutes (1200 seconds)
            $authNamespace->timeout = time() + 1200;
            // If possible, redirect to the page we came from (see the
            // preDispatch routine).  Otherwise, go to the main index page.
            if (isset($authNamespace->requestUri)) {
                $this->_redirect($authNamespace->requestUri);
            } else {
                $this->_redirect('/');
            }
        }
    }
    // ...
In all the other controllers, I added a preDispatch() function, which is a hook provided by Zend to perform non-standard functions:

Code:
<?php
// IndexController.php (or any other controller other than LoginController)

class IndexController extends Zend_Controller_Action
{
    function preDispatch()
    {
        $authNamespace = new Zend_Session_Namespace('auth');
        // clear the identity of a user who has not accessed a controller for
        // longer than a timeout period.
        if (isset($authNamespace->timeout) && time() > $authNamespace->timeout) {
            Zend_Auth::getInstance()->clearIdentity();
        } else {
            // User is still active - update the timeout time.
            $authNamespace->timeout = time() + 1200;
            // Store the request URI so that an authentication after a timeout
            // can be directed back to the pre-timeout display.  The base URL needs to
            // be stripped off of the request URI to function properly.
            $authNamespace->requestUri = substr($this->_request->getRequestUri(),
                strlen(Zend_Controller_Front::getInstance()->getBaseUrl()));
        }
        // If the user has no identity here, there has either been a time out or the user has
        // not logged in yet.
        if (!Zend_Auth::getInstance()->hasIdentity()) {
            $this->_redirect('/Login/login');
        }
    }
    // ...
There is one downside to this code: after a timeout re-authentication, control returns back to where the user was at timeout (i.e., it does not follow the current request). To me, this is a fairly minor problem.

This code seems to work fine on these configurations:

Zend Framework v1.5.2 on Linux or OS-X
PHP v5.2.6 on Linux or OS-X
Apache v2.2.9 on Linux or OS-X
Firefox v3.0 on Linux
Konqueror v3.5.7 on Linux
Firefox v2.0.0.14 on OS-X
Safari v3.1.1 on OS-X
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 08-26-2008, 08:35 PM
Junior Member
 
Join Date: Aug 2008
Posts: 2
Default

check the next message

Last edited by brreddy : 08-26-2008 at 08:49 PM. Reason: duplicate message
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 08-26-2008, 08:38 PM
Junior Member
 
Join Date: Aug 2008
Posts: 2
Default

Instead of adding preDispatch in all controllers you can register a plugin to Zend_Controller_Front and handle timeout in it.

in bootstrap:
Quote:
...
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory('controllers');
$front->registerPlugin(new TimeoutHandlerPlugin());
$front->dispatch();
...
timeout handler plugin:

Quote:
class TimeoutHandlerPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request) {
// reset the timer here
}
}
Cheers,
Ravi
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 09-02-2008, 04:25 AM
Member
 
Join Date: Jun 2008
Location: Florida
Posts: 94
Default

The long and the short of it: you need to reset the setExpirationSeconds method on every request if you want to have a sliding timeout.

I think a plugin is a way to go. No need to add code to every controller.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 11:47 PM.