Skip to content

Instantly share code, notes, and snippets.

@moaalaa
Created June 8, 2018 17:16
Show Gist options
  • Save moaalaa/df19006ad4ca0dbe782f1a94ea814f5f to your computer and use it in GitHub Desktop.
Save moaalaa/df19006ad4ca0dbe782f1a94ea814f5f to your computer and use it in GitHub Desktop.
<?php
class CustomSessionHandler extends \SessionHandler
{
private $sessionName = 'SESSION_NAME';
private $sessionMaxLifeTime = 0;
private $sessionSSL = true;
private $sessionHTTPOnly = true;
private $sessionPath = '/';
private $sessionDomain = '127.0.0.1'; // EX: .domain.com
private $sessionSavePath = 'SESSION_SAVE_PATH';
private $sessionCipherAlgo = 'AES-128-CBC';
private $sessionCipherKey = 'SESSION_CIPHER_KEY'; // EX: CREPT0K3Y@2018
private $ttl = 30;
public function __construct()
{
$this->sessionSSL = isset($_SERVER['HTTPS']) ? true : false;
$this->sessionDomain = str_replace('www.', '', $_SERVER['SERVER_NAME']);
// initialize some directive
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.use_trans_sid', 0);
ini_set('session.save_handler', 'files');
// Define the basic session information
session_name($this->sessionName);
session_save_path($this->sessionSavePath);
session_set_cookie_params($this->sessionMaxLifeTime, $this->sessionPath, $this->sessionDomain, $this->sessionSSL, $this->sessionHTTPOnly);
// session_set_save_handler($this, true);
}
public function __get($key)
{
// TODO: Need some improvements
if (isset($_SESSION[$key])) {
// unserialize
$data = @unserialize($_SESSION[$key]);
// check if the unserialize data is real data or false because we serialize object data when storing it
if ($data === false) return $_SESSION[$key];
return $data;
} else {
return null;
}
}
public function __set($key, $value)
{
if (is_object($value)) {
$_SESSION[$key] = serialize($value);
} else {
$_SESSION[$key] = $value;
}
}
public function __isset($key)
{
return isset($_SESSION[$key]) ? true : false;
}
public function read($session_id)
{
return openssl_decrypt(parent::read($session_id), $this->sessionCipherAlgo, $this->sessionCipherKey);
}
public function write($session_id, $session_data)
{
$encryptedData = openssl_encrypt($session_data, $this->sessionCipherAlgo, $this->sessionCipherKey);
return parent::write($session_id, $encryptedData);
}
public function start()
{
if ('' === session_id()) {
if (session_start()) {
$this->setSessionStartTime();
$this->checkSessionExpiration();
}
}
}
private function setSessionStartTime()
{
// set session start time
if (!isset($this->sessionStartTime)) {
$this->sessionStartTime = time();
}
return true;
}
private function checkSessionExpiration()
{
if ((time() - $this->sessionStartTime) > ($this->ttl * 60)) {
$this->generateNewSession();
$this->generateFingerPrint();
var_dump(time() - $this->sessionStartTime);
}
return true;
}
private function generateNewSession()
{
$this->sessionStartTime = time();
return session_regenerate_id(true);
}
public function close()
{
session_unset(); // unset all session variables
session_destroy(); // destroy the session completely
session_write_close(); // close the session write
setcookie(session_name(), '', 0, $this->sessionPath, $this->sessionDomain, $this->sessionSSL, $this->sessionHTTPOnly);
// Suspend the error to avoid [ "session_regenerate_id cannot generate new session because session is not active" ]
@session_regenerate_id(true); // if not needed remove it but old session file will not deleted
}
private function generateFingerPrint()
{
// generate finger print to prevent session hijacking and fixation
$userAgentId = $_SERVER['HTTP_USER_AGENT'];
$this->cipherKey = openssl_random_pseudo_bytes(16);
$sessionId = session_id();
$this->fingerPrint = md5($userAgentId . $this->cipherKey . $sessionId);
}
public function isFingerPrintExpire()
{
if (! isset($this->fingerPrint)) {
$this->generateFingerPrint();
}
$fingerPrint = md5($_SERVER['HTTP_USER_AGENT'] . $this->cipherKey . session_id());
if ($fingerPrint === $this->fingerPrint) return true;
return false;
}
public function gc($maxLifetime)
{
parent::gc($maxLifetime);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment