Das ganze System ist zwar noch nicht ganz ausgereift, aber ich kann mal die Kernstuecke posten.
In der login.php hab ich folgendes am Anfang:
PHP-Code:
<?php
require_once dirname( __FILE__ ) . '/include/config/config.inc.php';
if ( !$session->requireNewSession() ) {
redirectTo( 'index.php' );
}
if ( isset( $_POST['usr_login'] ) && isset( $_POST['usr_pass'] ) ) {
$user = new User();
if ( $user->exists( $_POST['usr_login'], md5( $_POST['usr_pass'] ) ) ) {
$_SESSION['sss_usr'] = $user->getAttribute( 'usr_id' );
$session->registerNewSession( $_SESSION['sss_usr'] );
if ( !$session->requireNewSession() ) {
if ( count( $emess ) > 0 )
$_SESSION['sss_usr'] = -1;
redirectTo( 'index.php' );
}
}
}
?>
In $emess stehen dabei die Meldungen, die aufgetreten sind, als man sich versucht hat anzumelden. Im Fall vom zweiten Login waere das zum Beispiel die Fehlermeldung von MySQL, dass der Benutzer schon angemeldet ist.
Die MySQL-Tabelle dazu sieht so aus:
Code:
CREATE TABLE `usm_session` (
`sss_id` int(11) unsigned NOT NULL auto_increment,
`sss_usr` int(11) unsigned NOT NULL default '0',
`sss_ip` varchar(25) NOT NULL default '',
`sss_port` varchar(255) NOT NULL default '',
`sss_tstamp` timestamp(14) NOT NULL,
PRIMARY KEY (`sss_id`),
UNIQUE KEY `sss_usr` (`sss_usr`)
) ENGINE=MyISAM AUTO_INCREMENT=47 ;
die User-id ist unique, deshalb bekomm ich dann immer die Meldung!
Im Prinzip sollte damit alles gesagt sein.
Vielleicht die Session-Klasse noch:
PHP-Code:
<?php
class Session {
function Session() {
}
function requireNewSession() {
$result = TRUE;
$config =& $GLOBALS['config'];
$database = new Database( $config );
$database->connect();
$database->selectDB();
$timeout = $config->getValue( 'timeout' );
$select = $this->_startSession( $timeout );
if ( $select->getRowNums() == 1 ) {
$result = FALSE;
} else {
$this->_destroySession( $timeout );
$result = TRUE;
}
$select->freeResult();
$database->disconnect();
return $result;
}
function registerNewSession( $userId ) {
$database = new Database( $GLOBALS['config'] );
$database->connect();
$database->selectDB();
$fields = array( 'sss_usr' => $userId, 'sss_ip' => $_SERVER['REMOTE_ADDR'],
'sss_port' => $_SERVER['REMOTE_PORT'],
'sss_tstamp' => date( 'YmdHis', mktime() ) );
$insert = new Insert( 'usm_session', $fields );
$insert->execQuery();
$database->disconnect();
}
function _startSession( $timeout ) {
$timeout = $this->_getCorrectTimeoutCalc( $timeout );
$select = new Select( NULL, 'usm_session' );
$select->addWhere( array( 'sss_usr' => $_SESSION['sss_usr'] ) );
$select->addWhere( array( 'sss_tstamp' => $timeout ), '>', 'AND' );
$select->execQuery();
return $select;
}
function _destroySession( $timeout ) {
$timeout = $this->_getCorrectTimeoutCalc( $timeout );
$delete = new Delete( 'usm_session' );
$delete->addWhere( array( 'sss_usr' => $_SESSION['sss_usr'] ) );
$delete->addWhere( array( 'sss_tstamp' => $timeout ), '<', 'AND' );
$delete->execQuery();
}
function _getCorrectTimeoutCalc( $timeout ) {
$now = date( 'YmdHis', mktime() );
return "'$now' - '$timeout'";
}
};
?>
Die Klassen Database, Select, Insert, Delete, User und Config poste ich mal nicht, das wird zu viel. Und das Abmelden fehlt noch.
Und damit sind wir auch schon beim Problem das auftreten kann!
Wenn man z.B. irgendwo eingelogged ist und beendet die Sitzung nicht regulaer, dann kann sich derselbe Bentuzer solange nicht mehr anmelden bis das Timeout eingetreten ist - man muesste also den Session-Eintrag von Hand loeschen, dann kann er sich wieder anmelden!
mfg
P.S.: Waer das von Microsoft waerde das sicher ein Feature und kein Fehler
Lesezeichen