diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 32a83259e3..6b6aca8227 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.8 under development ----------------------- +- Bug #6173: Added property `yii\web\DbSession::encodeData` to encode/decode session data in base64 on session read/write (silverfire) - Bug #9851: Fixed partial commit / rollback in nested transactions (sammousa) - Bug #10946: Fixed parameters binding to the SQL query in `yii\db\mysqlSchema::findConstraints()` (silverfire) - Enh #5469: Add mimetype validation by mask in FileValidator (kirsenn, samdark, silverfire) diff --git a/framework/web/DbSession.php b/framework/web/DbSession.php index 108e94ba19..fd8e110d3d 100644 --- a/framework/web/DbSession.php +++ b/framework/web/DbSession.php @@ -73,7 +73,12 @@ class DbSession extends MultiFieldSession * length 64 instead of 40. */ public $sessionTable = '{{%session}}'; - + /** + * @var boolean whether to encode the session data to base64. Defaults to false. + * The parameter can be useful for PgSQL DBMS where serialised session + * @since 2.0.8 + */ + public $encodeData = false; /** * Initializes the DbSession component. @@ -145,7 +150,7 @@ class DbSession extends MultiFieldSession } $data = $query->select(['data'])->scalar($this->db); - return $data === false ? '' : $data; + return $data === false ? '' : $this->encodeData ? base64_decode($data) : $data; } /** @@ -166,6 +171,7 @@ class DbSession extends MultiFieldSession ->where(['id' => $id]) ->createCommand($this->db) ->queryScalar(); + $data = $this->encodeData ? base64_encode($data) : $data; $fields = $this->composeFields($id, $data); if ($exists === false) { $this->db->createCommand() diff --git a/tests/framework/web/DbSessionTest.php b/tests/framework/web/DbSessionTest.php index 8e6057df97..38b63349f7 100644 --- a/tests/framework/web/DbSessionTest.php +++ b/tests/framework/web/DbSessionTest.php @@ -3,6 +3,7 @@ namespace yiiunit\framework\web; use Yii; +use yii\db\ActiveQuery; use yii\db\Connection; use yii\db\Query; use yii\web\DbSession; @@ -41,6 +42,21 @@ class DbSessionTest extends TestCase $this->assertEquals('', $session->readSession('test')); } + public function testEncodeDataRW() + { + $session = new DbSession(['encodeData' => true]); + + $session->writeSession('test', 'session data'); + $session->id; + + $data = (new Query())->select(['data'])->from('session')->where(['id' => 'test'])->scalar(); + $this->assertNotRegExp('~[^0-9a-zA-Z+/=]~', $data, 'The session data contains non-base64 characters'); + + $this->assertEquals('session data', $session->readSession('test')); + $session->destroySession('test'); + $this->assertEquals('', $session->readSession('test')); + } + /** * @depends testReadWrite */ @@ -82,4 +98,4 @@ class DbSessionTest extends TestCase $this->assertEquals('session data', $sessionRow['data']); $this->assertEquals(15, $sessionRow['user_id']); } -} \ No newline at end of file +}