Yii2: Problems with using CasheSession and User::enableAutoLogin

Created on 7 Feb 2017  Â·  1Comment  Â·  Source: yiisoft/yii2

What steps will reproduce the problem?

To run CacheSession use this settings:

'user' => [
  'identityClass'   => common\modules\user\models\User::className(),
  'enableAutoLogin' => true, // use autologin
],
'session' => [
  'class'        => yii\web\CacheSession::className(), // cache == MemCache
  'cookieParams' => [
    'lifetime' => 10, // to fast detect the problems
  ],
],

Sign in the app with Remember me checkbox and wait for 10 seconds. After this time the session automatically ended. Then I click "Logout" link.

What is the expected result?

User must simply logged out.

What do you get instead?

In debug mode the site is throwing the warning:

PHP Warning – yii\base\ErrorException
session_regenerate_id(): Session object destruction failed. ID: user (path: /var/lib/php/sessions)

What is the problem?

When we are using enableAutoLogin and clicking to the Logout link, there are two steps in one request: first step is Loging in by cookie to the app, and second step Loging out. Both steps are accompanied by regenerateID method:

    /**
     * Updates the current session ID with a newly generated one .
     * Please refer to <http://php.net/session_regenerate_id> for more details.
     * @param boolean $deleteOldSession Whether to delete the old associated session file or not.
     */
    public function regenerateID($deleteOldSession = false)
    {
        if ($this->getIsActive()) {
            // add @ to inhibit possible warning due to race condition
            // https://github.com/yiisoft/yii2/pull/1812
            if (YII_DEBUG && !headers_sent()) {
                session_regenerate_id($deleteOldSession); // there is our problem place
            } else {
                @session_regenerate_id($deleteOldSession);
            }
        }
    }

In Loging in step this method is not running, because the session is not yet active. But session is activated after login and on second step session ID will be regenerated. All would be good, but session_regenerate_id is trigger other method - CacheSession::destroySession($id):

    /**
     * Session destroy handler.
     * Do not call this method directly.
     * @param string $id session ID
     * @return boolean whether session is destroyed successfully
     */
    public function destroySession($id)
    {
        return $this->cache->delete($this->calculateKey($id));
    }

This is our problem, because the cache cannot find the data by new generated key and throwing false.
Maybe this it`s wrong, but the error occurs all the time.
I think, check the key in cache before delete will solve the problem.
For example:

    public function destroySession($id)
    {
        return !$this->cache->exists($this->calculateKey($id)) || $this->cache->delete($this->calculateKey($id));
    }

Additional info

PS: Sorry for my Eng :-)

| Q | A
| ---------------- | ---
| Yii version | 2.0.10
| PHP version | 7.0
| Operating system | Ubuntu 14.04 x64

bug

Most helpful comment

The problem is verified, thank you for the report.

DbSession always returns true from destroySession() method, so the problem can be reproduced only with CacheSession component.

>All comments

The problem is verified, thank you for the report.

DbSession always returns true from destroySession() method, so the problem can be reproduced only with CacheSession component.

Was this page helpful?
0 / 5 - 0 ratings