|_|0|_|
|_|_|0|
|0|0|0|

Be-Paranoid.net

Sessionverwaltung über MySQL

Orginal Version | Artikel editieren | Versionen anzeigen | Bottom
Letzte Änderung: 20.05.2009, 22:59

Inhaltsverzeichnis



Code Top


Der folgende Code verlagert die Session-Verwaltung von PHP in eine MySQL-Datenbank. Bei der Implementierung wurde besonders auf Sicherheit geachtet.

Code:


$salt = 'salzig';

ini_set('session.use_only_cookies', '1');

session_set_save_handler('_open','_close','_read','_write','_destroy','_clean');

function _open() {
    global $conn;
    global $salt;

    if ( ($conn = mysql_connect($mysql_host, $mysql_user, $mysql_passwort)) && mysql_select_db($mysql_datenbank, $conn) ) {
        if ( $id = session_id() ) {
            $id = mysql_real_escape_string($id, $conn);
            $ipagent = '';
            
            if ( mysql_num_rows( $query = mysql_query("SELECT `ipagent` FROM `user_sessions` WHERE `id` = '{$id}'", $conn) ) )
                $ipagent = mysql_result($query,0);

            if ( $ipagent != md5($salt.$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR']) )
                session_regenerate_id();
        }
    }
    else
        return FALSE;
}

function _close() {
    global $conn;

    return mysql_close($conn);
}

function _read($id) {
    global $conn;

    $id = mysql_real_escape_string($id, $conn);

    if ( mysql_num_rows( $query = mysql_query("SELECT `data` FROM `user_sessions` WHERE `id` = '{$id}'", $conn)) )
        return mysql_result($query, 0);
    return '';
}

function _write($id, $data) {
    global $conn;
    global $salt;
    
    $access = mysql_real_escape_string(time(), $conn);
    $id = mysql_real_escape_string($id, $conn);
    $data = mysql_real_escape_string($data, $conn);
    $ipagent = mysql_real_escape_string(md5($salt.$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR']), $conn);

    return mysql_query("REPLACE INTO `user_sessions` (`id`,`access`,`data`,`ipagent`) VALUES ('{$id}','{$access}','{$data}','{$ipagent}')", $conn);
}

function _destroy($id) {
    global $conn;

    $id = mysql_real_escape_string($id, $conn);

    return mysql_query("DELETE FROM `user_sessions` WHERE `id` = '{$id}'", $conn);
}

function _clean($max) {
    global $conn;

    $max = mysql_real_escape_string(time() - $max, $conn);

    return mysql_query("DELETE FROM `user_sessions` WHERE `access` < '{$max}'", $conn);
}



Weiters ist dazu eine Tabelle mit folgender Struktur erforderlich

MySQL-DB:


CREATE TABLE `user_sessions` (
  `id` varchar(32) NOT NULL default '',
  `access` int(10) unsigned default NULL,
  `data` text default NULL,
  `ipagent` varchar(32) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM;



bzw. für Tabellen im RAM (schneller, funktioniert jedoch erst ab MySQL 5.0.3):

MySQL-DB:


CREATE TABLE `user_sessions` (
  `id` varchar(32) NOT NULL default '',
  `access` int(10) unsigned default NULL,
  `data` varchar(1024) default NULL,
  `ipagent` varchar(32) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MEMORY;



Für die Spalte data kann dabei ein Varchar mit bis zu 65.535 Zeichen verwendet werden.

Optimierung Top


Die Funktion _clean() kann dabei auch dazu genutzt werden, um alte User-Accounts aufzuräumen. Sie wird bei PHP ungefähr alle 100 Seitenaufrufe einmal ausgeführt und eignet sich daher besonders für Aktionen, welche zwar gelegentlich, aber nicht immer erledigt werden müssen.

Wie oft _clean ausgeführt wird, kann über ini_set(session.gc_probability, WERT); und ini_set(session.gc_divisor, WERT); eingestellt werden. Dabei gilt:
probability/divisor = Wahrscheinlichkeit der Ausführung in %.

Weblinks Top


PHP Session Referenz


Achtung! Top


Auf dieser Seite wird davor gewarnt den session_set_save_handler zu benutzen. UNBEDINGT DURCHLESEN!!!
Evtl. kann hier jemand eine Lösung posten.

Orginal Version | Artikel editieren | Versionen anzeigen | Top
Letzte Änderung: 20.05.2009, 22:59