Har börjat jobba med en ny inloggningsklass i PHP - än så länge bara en sessionhandler.
Tänkte först starta en ny tråd men kom på att jag nog hade en gammal.
class SessionManager {
function __construct() {
// set our custom session functions.
session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($this, 'gc'));
// This line prevents unexpected effects when using objects as save handlers.
register_shutdown_function('session_write_close');
}
function start_session($session_name, $secure) {
// Make sure the session cookie is not accessable via javascript.
$httponly = true;
$session_hash = 'whirlpool';
// Check if whirlpool is available
if (in_array($session_hash, hash_algos())) {
// Set the has function.
ini_set('session.hash_function', $session_hash);
}
// How many bits per character of the hash.
// The possible values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ",").
ini_set('session.hash_bits_per_character', 5);
// Force the session to only use cookies, not URL variables.
ini_set('session.use_only_cookies', 1);
// Get session cookie parameters
$cookieParams = session_get_cookie_params();
// Set the parameters
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly);
// Change the session name
session_name($session_name);
// Now we can start the session
session_start();
// This line regenerates the session and delete the old one.
// It also generates a new encryption key in the database.
session_regenerate_id(true);
}
function open() {
$sess_db = new PDO('mysql:host=localhost;dbname=sec_sessions', 'sess_usr', 'password');
$sess_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Kommer självklart inte köra ERRMODE_EXCEPTION i skarp version
$this->db = $sess_db;
return true;
}
function read($id) {
if(!isset($this->read_stmt)) {
$this->query = $this->db->prepare("SELECT data FROM sessions WHERE id = ? LIMIT 1");
}
$this->query->execute(array($id));
$row = $this->query->fetchAll(PDO::FETCH_ASSOC);
$data = $row[0];
$data = $data['data'];
$key = $this->getkey($id);
$data = $this->decrypt($data, $key);
return $data;
}
function write($id, $data) {
// Get unique key
$key = $this->getkey($id);
// Encrypt the data
$data = $this->encrypt($data, $key);
$time = time();
if(!isset($this->w_stmt)) {
$this->w_stmt = $this->db->prepare("REPLACE INTO sessions (id, set_time, data, session_key) VALUES (:id, :time, :data, :key)");
}
$params = array('id' => $id,'time' => $time,'data' => $data,'key' => $key);
$this->w_stmt->execute($params);
return true;
}
function destroy($id) {
if(!isset($this->delete_stmt)) {
$this->delete_stmt = $this->db->prepare("DELETE FROM sessions WHERE id=:id");
}
$this->delete_stmt->bindValue(':id', $id, PDO::PARAM_STR);
$this->delete_stmt->execute();
if ($this->delete_stmt->rowCount() > 0) {
return true;
} else {
$this->errmsg .= "Failed to delete session from DB. \n";
return false;
}
}
function close() {
return true;
}
function gc($max) {
if(!isset($this->gc_stmt)) {
$this->gc_stmt = $this->db->prepare("DELETE FROM sessions WHERE set_time < :old");
}
$old = time() - $max;
$this->gc_stmt->bindValue(':old', $old, PDO::PARAM_STR);
$this->gc_stmt->execute();
return true;
}
private function getkey($id) {
if(!isset($this->key_stmt)) {
$this->key_stmt = $this->db->prepare("SELECT session_key FROM sessions WHERE id = ? LIMIT 1");
}
$this->key_stmt->execute(array($id));
if($this->key_stmt->rowCount() == 1) {
$row = $this->key_stmt->fetchAll(PDO::FETCH_ASSOC);
$row = $row[0];
return $row['session_key'];
} else {
$random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
return $random_key;
}
}
private function encrypt($data, $key) {
$salt = 'cH!swe!ASÖUOIFHD=(D/ASFHÖKJH(/oijhKJASas*ewr4n39=E@rAsp7c-Ph@pH';
$key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv));
return $encrypted;
}
private function decrypt($data, $key) {
$salt = 'cH!swe!ASÖUOIFHD=(D/ASFHÖKJH(/oijhKJASas*ewr4n39=E@rAsp7c-Ph@pH';
$key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv);
return $decrypted;
}
}
Och så är jag lite förvirrad. Om jag t. ex. skall förstöra en session vid en utloggning; ska jag köra $SessionManager->destroy() ? Isf behöver jag ju ha id till sessionen, och hur får jag fram det?