Created
June 8, 2018 17:16
-
-
Save moaalaa/df19006ad4ca0dbe782f1a94ea814f5f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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