Anzeige:
Ergebnis 1 bis 10 von 10

Thema: Sessionklasse

  1. #1
    Registrierter Benutzer
    Registriert seit
    15.10.2005
    Ort
    Franken
    Beiträge
    362

    Sessionklasse

    Hallo,

    ich suche eine Sessionklasse, die auf eine Datenbank (MySQL MEMORY/HEAP) aufsetzt.
    Nein, besser: Mit der ich mit einem Script alle Sessions, die laufen, ansehen und bearbeiten / löschen kann. Insbesondere soll ein "Doppellogin" eines Users verhindert werden. Eine solche muss aber wohl auf eine Datenbank aufsetzen, was ich auch für ok halte, RAM steht genug zur Verfügung.

    Weitere Anforderungen:
    - Lesbarer Code
    - Sessionvariablen als einfache Variablen und Arrays, Objekte nicht notwendig
    - Lösung über Cookies, Fallbacksystem nicht notwendig

    Ich lege mehr wert auf Performance als auf Flexibilität.

    Natürlich habe ich auch schon selbst gesucht, frage aber nochmal, welche dieser Klassen ihr einsetzt.

    Gruß

    Turbohummel
    Dank der Rekursion kann ich IF-Schleifen bauen.

    In neuem Glanz: www.turbohummel.de

  2. #2
    Registrierter Benutzer Avatar von Gaert
    Registriert seit
    09.05.2002
    Ort
    Nußloch
    Beiträge
    1.317
    Hallo,

    Ich benutze eine eigene Klasse für das Session handling zum speichern der Session in einer Datenbank - ließe sich auch erweitern für Shared Memory, wenn man sehr viel Wert auf Performance legt. Das ganze basiert auf dem Standard Session Management von PHP - ich lege die Daten lediglich woanders ab. Wenn du ein beispiel brauchst kann ich sie dir mal schicken (per pm melden), ansonsten reichts eigentlich sich die Session Funktionen anzusehen und die User Comments zu lesen: http://de2.php.net/session

    Gruß,

    Gaert


  3. #3
    Registrierter Benutzer
    Registriert seit
    15.10.2005
    Ort
    Franken
    Beiträge
    362
    Hallo,

    inzwischen hab ich ne Lösung entwickelt, die mein Problem (absolut sicheres Verhindern von Doppellogins - das wäre für den Zweck nämlich tödlich) viel einfacher lösen. Beim Erzeugen einer Session (sprich beim Login) wird in einer MySQL-Heap-Tabelle "active_sessions" (Felder: session_id, user_id, start) ein "DELETE FROM active_sessions WHERE user_id = xxx LIMIT 1" ausgeführt und die neue Session eingetragen. Bei jedem Seitenaufruf gucke ich in die Tabelle, ob die Session-id noch eingetragen ist. Wenn nein -> Session beenden.

    Einfach, aber genau das was ich will (wieder mal einer meiner Ideen, die ich Nachts um 3 hatte).
    Dank der Rekursion kann ich IF-Schleifen bauen.

    In neuem Glanz: www.turbohummel.de

  4. #4
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    377
    Ich hab das so geloest dass wenn fuer einen Benutzer bereits eine Session existiert er ueberhaupt nicht mehr auf die Login-Seite kommt sondern immer auf die Hauptseite zurueckgeleitet wird.
    Amilo D - 2,8 Ghz - ATI Radeon 9000
    Debian GNU/Linux 3.1 (Sarge)

  5. #5
    Registrierter Benutzer
    Registriert seit
    15.10.2005
    Ort
    Franken
    Beiträge
    362
    Das löst das Problem nicht, wenn der User sich von nem anderen PC aus einloggt - was ja eben verhindert werden soll.
    Dank der Rekursion kann ich IF-Schleifen bauen.

    In neuem Glanz: www.turbohummel.de

  6. #6
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    377
    Doch, es wird ja ueberprueft ob der Benutzer schon angemeldet ist - und wenn das so ist wird er einfach mit ner Fehlermeldung wieder zum Login geschickt!
    Amilo D - 2,8 Ghz - ATI Radeon 9000
    Debian GNU/Linux 3.1 (Sarge)

  7. #7
    Registrierter Benutzer
    Registriert seit
    15.10.2005
    Ort
    Franken
    Beiträge
    362
    Da würd ich gerne mal den Code sehen, um das auszuprobieren.
    Dank der Rekursion kann ich IF-Schleifen bauen.

    In neuem Glanz: www.turbohummel.de

  8. #8
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    377
    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 ) > )
                        
    $_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() == ) {
                    
    $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 SelectNULL'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
    Geändert von nul (17-03-2006 um 11:17 Uhr)
    Amilo D - 2,8 Ghz - ATI Radeon 9000
    Debian GNU/Linux 3.1 (Sarge)

  9. #9
    Registrierter Benutzer
    Registriert seit
    13.08.2004
    Ort
    Bonn
    Beiträge
    15
    Das einfachste ist wirklich beim Start einer Session die Einträge zu löschen, die unter der gleichen ID gespeichert sind. Das ist ziemlich robust.

  10. #10
    Registrierter Benutzer
    Registriert seit
    15.10.2005
    Ort
    Franken
    Beiträge
    362
    @PierreS: Jop, mach ich ja auch so.

    So ähnlich hab ich das auch gelöst, hattest du nur mit
    Ich hab das so geloest dass wenn fuer einen Benutzer bereits eine Session existiert er ueberhaupt nicht mehr auf die Login-Seite kommt sondern immer auf die Hauptseite zurueckgeleitet wird.
    nicht ganz so beschrieben, oder steh ich da auf dem Schlauch?

    Als Tabellentyp würde ich HEAP nehmen, das ist für die Performance (in 99% der Fälle) förderlich.
    Dank der Rekursion kann ich IF-Schleifen bauen.

    In neuem Glanz: www.turbohummel.de

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •