1

I am working on a project which is built using CakePHP 2.8 . At the time of login I am setting a FLAG to 1 and on logout it is set to 0, so that account can be logged in on single computer at a time. It is working great till this part.

The problem I am facing is at the SESSION TIMEOUT. I am confused that how to set the flag to 0 in database when session timeout. Is there any way to run an update query on session timeout.

I am using the CORE config file to set the SESSION timeout limit as follow:

Configure::write('Session', array(
    'defaults' => 'php',
    'timeout' => 30, // The session will timeout after 30 minutes of inactivity
    'cookieTimeout' => 1440, // The session cookie will live for at most 24 hours, this does not effect session timeouts
    'checkAgent' => false,
    'autoRegenerate' => true, // causes the session expiration time to reset on each page load
));

And this is my logout function

public function logout() {
    $id = $this->Auth->User('id');
    $this->User->updateAll(array('WebLoggedIn'=>0), array('User.id'=>$id));
    $this->Auth->logout();
    // redirect to the home
    return $this->redirect('/');
}
AD7six
  • 63,116
  • 12
  • 91
  • 123
Sam B
  • 80
  • 1
  • 11
  • Please check this http://stackoverflow.com/questions/37948391/prevent-ajax-calls-from-updating-session-timeout-with-cakephp. Some of answer you can do here – madankundu Sep 29 '16 at 08:37

1 Answers1

1

That won't work

The idea in the question isn't going to work. The moving parts related to sessions, with the config in the question are:

  • A file stored on the server with the serialized session data in it, which updates every time the session is written to
  • A standard php cron job, which deletes session files that have expired (see /etc/cron.d/php5 or equivalent)
  • A browser cookie, which links the user's browser session to the file on the server

When a user's session time's out - that either means the session id they presented does not correspond to a file on the server, or they simply didn't present a session cookie. There's no "hey this session expired" event at the moment it expires, and there's no guarantee a user would provide the old session id for you to check if it's valid.

Working proposal

A simple (and this also means naïve and possibly easy to bypass) solution is to not store a boolean, and instead store the time their session will expire in the db. I.e. have code similar to this:

// App Controller
public function beforeFilter()
{
    $userId = $this->Auth->user('id');
    if ($userId) {
        $this->User->updateAll(
            array('active_session_expires'=> time() + (30 * 60)), 
            array('User.id'=>$id)
        );
    }
}

And in the users controller:

public function login() {
    if ($this->request->is('post')) {
        if ($this->Auth->login()) {
            if ($this->Auth->user('active_session_expires') > time()) {
                $this->Flash->error('You are still logged in somewhere else');
                return $this->logout();
            }

            $this->User->updateAll(
                array('active_session_expires'=> time() + (30 * 60)), 
                array('User.id'=> $this->Auth->user('id'))
            );
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error(__('Invalid username or password, try again'));
    }
}

public function logout()
{
    $id = $this->Auth->User('id');
    if ($id) {
        $this->User->updateAll(
            array('active_session_expires'=> time()),
            array('User.id'=>$id)
        );
        $this->Auth->logout();
    }
    return $this->redirect('/');
}

I.e. every time they do something - update the db to keep track of their activity. If they try to login before their existing session expires - immediately log them out. Expect to need to test/modify this example code, it is provided to give you an idea, not necessarily a complete and working solution.

This is similar to an answer you've already been linked to.

Community
  • 1
  • 1
AD7six
  • 63,116
  • 12
  • 91
  • 123
  • thanks for the suggestion but the above function will kick out the user after 30 min even if the user is active. I want to end the session at inactivity of 30 min. Any suggestion to do it @AD7six – Sam B Sep 29 '16 at 10:50
  • I think you've misread the answer, this is not true `the above function will kick out the user after 30 min even if the user is active`. There is no code to log a user out, _except_ if they attempt to login - and only the attemping-to-login session is logged out. – AD7six Sep 29 '16 at 12:13
  • Sorry my mistake, I read it wrong. But if I use above code how can i check if the user is inactive for 30 min, then it need to be logged out and also reset the flag at that time. @AD7six – Sam B Sep 29 '16 at 12:45
  • `then it need to be logged out` - ? You don't, that's what the `Session.timeout` config setting is for. If you do want to do literally what you've asked read the `active_session_expires` value and use that however you want. – AD7six Sep 29 '16 at 12:49