php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #75047 session_regenerate_id fails with redis
Submitted: 2017-08-08 10:05 UTC Modified: 2017-09-05 23:00 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: bartosz at kibilko dot pl Assigned: yohgaki (profile)
Status: Assigned Package: Session related
PHP Version: 7.0.22 OS: Ubuntu / Docker Container
Private report: No CVE-ID: None
 [2017-08-08 10:05 UTC] bartosz at kibilko dot pl
Description:
------------
PHP 7.0.21
phpredis 3.1.2
redis 3.0.7 / 3.2.4
Magento 1.14.2.4

Context:
There are some problems with session_regenerate_id  function when redis is used as session adapter. Currently, I'm trying to login in Magento and session_id is stored in redis and in cookies but nothing happens - user is not logged in. When I remove the cookie, PHP throws this:

Recoverable Error: session_regenerate_id(): Failed to create(read) session ID: redis (path: tcp://redis:6379/?database=2).

It can be also related to phpredis, because version 3.1.3 has another bug :) - https://github.com/phpredis/phpredis/issues/1211 

Expected result:
----------------
No errors, user logged in

Actual result:
--------------
Recoverable Error: session_regenerate_id(): Failed to create(read) session ID: redis (path: tcp://redis:6379/?database=2)  in /var/www/mage/magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 141

#0 [internal function]: mageCoreErrorHandler(4096, 'session_regener...', '/var/www/magent...', 141, Array)
#1 /var/www/mage/magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php(141): session_regenerate_id(false)
#2 /var/www/mage/magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php(222): Mage_Core_Model_Session_Abstract_Varien->start('frontend')
#3 /var/www/mage/magento/app/code/core/Mage/Core/Model/Session/Abstract.php(84): Mage_Core_Model_Session_Abstract_Varien->init('core', 'frontend')
#4 /var/www/mage/magento/app/code/core/Mage/Core/Model/Session.php(42): Mage_Core_Model_Session_Abstract->init('core', 'frontend')
#5 /var/www/mage/magento/app/code/core/Mage/Core/Model/Config.php(1354): Mage_Core_Model_Session->__construct(Array)
#6 /var/www/mage/magento/app/Mage.php(471): Mage_Core_Model_Config->getModelInstance('core/session', Array)
#7 .........


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-09-05 06:20 UTC] ray at rayxis dot com
I'm also experiencing this in php 7.1.8. 

The reason that this problem exists is because PHP doesn't create the key in Redis if it doesn't exist. As a work-around, you need to create a key if one doesn't exist in the read() function of your session handler class. This removed the problem from my error logs:

public function read ($key)
{
    //	Get the session data and extend the expiration.
    $nkey  = $this->prefix . $key;
    read:
        $data = $this->sess->get($nkey);

    //	If nothing exists, create it first because PHP has a bug. :(
    if (!$data)
    {
        $this->write($key,TRUE);
        goto read;
    }

    $this->sess->expire($key, getenv('SESSTTL'));
    //	Return the result.
    return $data;
}
 [2017-09-05 08:40 UTC] yohgaki@php.net
> The reason that this problem exists is because PHP doesn't create the key 
> in Redis if it doesn't exist. As a work-around, you need to create a key if 
> one doesn't exist in the read() function of your session handler class. 
> This removed the problem from my error logs:

Thank you for useful info.

I take a look at the code for session save handler "read" and "write" in phpredis.
https://github.com/phpredis/phpredis/blob/develop/redis_session.c#L342
https://github.com/phpredis/phpredis/blob/develop/redis_session.c#L402

Session "read" does not send write command to redis for empty get, so it seems this is phpredis session save handler bug.

Save handlers are supposed to create session ID data entry either
 - open
 or 
 - read

When data is created is depends on underlying storage. For instance, "files" cannot create session data file with "read" since file is created when it is opened.

On the other hand, storage like redis/postgresql/etc cannot create session data with "open", but "read". "open" is supposed to open connection to db. "open" may create session data entry, though.

It seems this is phpredis issue, please close this bug if you get this fixed. If not, please let me know issue is in session.
 [2017-09-05 09:39 UTC] yohgaki@php.net
BTW, this is caused due to session_regenerate_id() behavior change from PHP 7.0.

PHP 5.6 and less
 - Old session data is not saved and creates new session without validating SID

PHP 7.0 and up
 - Old session data is saved and creates new session with SID validation.

From PHP 7.0, session save handlers are required not only to implement SID validation function, but also create session data either at "open" or "read" to make SID validation work. I might have missed this in UPGRADING.
 [2017-09-05 21:00 UTC] yohgaki@php.net
I missed to write upgrading note to UPGRADING. However, I wrote enough comments to
ttps://github.com/php/php-src/blob/master/ext/session/mod_files.c
for native session save handler developers as a reference implementation, but the comment is deleted by someone else.

I guess that's the reason why phpredis misses required code...
 [2017-09-05 21:32 UTC] yohgaki@php.net
It seems I missed to document it code, too :(
I'll update both UPGRADING and comment in the code.
 [2017-09-05 23:00 UTC] yohgaki@php.net
-Type: Bug +Type: Documentation Problem -Package: Unknown/Other Function +Package: Session related -Assigned To: +Assigned To: yohgaki
 [2017-09-05 23:00 UTC] yohgaki@php.net
Make this a doc bug.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Oct 11 06:01:27 2024 UTC