I'm trying to code a Custom SessionHandler while keeping the default "cake" session behaviour, which stores the session files in app/tmp/sessions/
By default, CakePHP 2.x saves session files as "sess_{sessionID}". What I would like to do is that those sessions are saved as "sess_{userID}-{sessionID}" for logged users, and "sess_000-{sessionID}" for not logged users that are in the login page and thus, have generated a session.
I've managed to make it create a few session files using both formats, but because of where I'm changing the session handler, it returns some errors as "Can't modify session save handler when there's an active session", or just doesn't log me in at all when trying my credentials...
ChatGPT has been more or less helpful in this task I'm trying to do. I have not been assigned this task directly, just wanted to fiddle around with the session to see if I could make it work.
This is my app/Model/Datasource/CustomSession.php:
<?php
// App::uses('CakeSession', 'Model/Datasource/Session');
class CustomSession extends SessionHandler implements SessionHandlerInterface {
public $cacheKey;
public function __construct() {
$this->cacheKey = Configure::read('Session.handler.cache');
}
// read data from the session.
public function read($id) {
$result = Cache::read($id, $this->cacheKey);
if ($result) {
return $result;
}
$id = $this->getModifiedId($id);
return parent::read($id);
}
// write data into the session.
public function write($id, $data) {
Cache::write($id, $data, $this->cacheKey);
$id = $this->getModifiedId($id);
return parent::write($id, $data);
}
// destroy a session.
public function destroy($id) {
Cache::delete($id, $this->cacheKey);
$id = $this->getModifiedId($id);
return parent::destroy($id);
}
// removes expired sessions.
public function gc($expires = null) {
Cache::gc($this->cacheKey);
return parent::gc($expires);
}
// get the modified session ID that includes the user ID
private function getModifiedId($id) {
$userId = CakeSession::read('Auth.User.id_for_session');
if ($userId) {
$id = $userId . '-' . $id;
}else{
$id = '000-' . $id;
}
return $id;
}
}
?>
And the beginning of my beforeFilter method in the AppController:
function beforeFilter() {
if($this->name == 'CakeError' && !$this->Auth->user()) {
$this->layout = 'login';
}
// Check if a session is already active
if (session_status() == PHP_SESSION_NONE) {
// Get the user ID
$userId = $this->Session->read('Auth.User.id_for_session');
// Create a new CustomSession object
$handler = new CustomSession($userId);
// Set the custom session handler
session_set_save_handler($handler, true);
// Start the session
session_start();
}
parent::beforeFilter();
// ...
}