Impressum · Kontakt · Hilfe
Besucher online · Mitglieder



Portal > Foren > PHP > PHP-Programmierung > SessionManagement: PHP-Sessions oder eigene Session-Klasse?
Antwort
 
Themen-Optionen
Alt 04.06.2006, 17:16   Nach oben    #1
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.590
Standard SessionManagement: PHP-Sessions oder eigene Session-Klasse?

Hallo,
aus aktuellen Anlass frage ich mich gerade, wo der Vorteil von einem eigenen gegenüber dem PHP-internen SessionManagement liegt und wie man dies am besten umsetzt, falls überhaupt sinnvoll.

Das Simple Machines Forum nutzt dies ja. Dort werden afaik die Sessiondaten in der Datenbank gespeichert!?

Ich persönlich sehe aber gar keinen Anhaltspunkt, warum das denn überhaupt besser sein sollte.
Geht es dort um Performance-/Sicherheitsaspekte oder nur um eine Abstraktion mehr im Gesamtsystem?

Würde mich über eine Diskussion diesbzgl. freuen.

Danke für Eure rege Teilnahme.
Grüße, Ben.
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:35   Nach oben    #2
MrNiceGuy
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 625
Standard

Ich persönlich sehe da wenn überhaupt eigentlich auch nur den Sinn drin, dass man bei einem eigenen System dieses besser in eine reine OOP-Umgebung bringen kann, aber das wars dann auch schon!? Ich kann mir nicht vorstellen, dass eine Funktion, die in PHP geschrieben wurde schneller sein soll, als eine Funktion, die in C geschrieben wurde und direkt in PHP kompiliert ist!?
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:37   Nach oben    #3
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.590
Standard

Jou, das glaube ich auch eher nicht. Sagen wir mal so .. ich wäre überrascht.

Bzgl.
Zitat:
Zitat von MrNiceGuy
dass man bei einem eigenen System dieses besser in eine reine OOP-Umgebung bringen kann
Wie würdest du das dann umsetzen, damit es auch einen Sinn ergibt?
Kleinen Codeschnipsel parat?
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:41   Nach oben    #4
Jay
Gast
 
Beiträge: n/a
Standard

Es geht nur um Sicherheitsaspekte. Eine weitere Abstraktionsschicht hast du nicht weil trotzdem über $_SESSION ganz normal zugegriffen wird.

Zur Sicherheit: Wenn deine Anwendung die einzige auf dem Server ist, so hilft dir das Sessionhandling über eine DB nichts. Da allerdings die meisten E-Commerce, CM Systeme auf Shared Hosts laufen, kann jeder User der Zugriff auf den Server hat die Sessiondaten und IDs auslesen. Sessions werden nämlich einfach in einem temporären Verzeichnis als Dateien am Server abgelegt. Durch die Einstellung session.save_path bekommt man den Pfad zum Verzeichnis. Jetzt kann man sich ein einfachs Script schreiben, dass dieses Verzeichnis öffnet die Dateien ausliest und ausliest. Damit ist es ein leichtes eine andere Anwendung am gleichen Server zu knacken.

Ein Script könnte so in etwa aussehen:
PHP-Code:
session_start ();
$handle dir (ini_get ("session.save_path"));
while (
$file $handle->read ()) {

   if (
substr ($file0,5)=="sess_") {
     
     ...
     ...

   }

Schreibt man jetzt allerdings die Daten in eine Datenbank, so sind darin sicher verwahrt, weil die anderen Nutzer ja keinen Username/Passwort dafür haben.

EDIT:

Zitat:
dass man bei einem eigenen System dieses besser in eine reine OOP-Umgebung bringen kann
Wie denn? session_start() funktioniert dann ja nicht!
Für ein eigenes Sessionhandling verwendet man session_set_save_handler (...), weil sich da praktisch PHP um alles kümmert und es schnell und effizient ist.

jay

Geändert von Jay (04.06.2006 um 17:46 Uhr).
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:42   Nach oben    #5
MrNiceGuy
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 625
Standard

Ich sagte nicht, dass ich das habe, ich sagte, dass es das einzige wäre, was in meinen Augen Sinn machen WÜRDE, man beachte den Konjunktiv
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:47   Nach oben    #6
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.590
Standard

Zitat:
Zitat von Jay
Es geht nur um Sicherheitsaspekte. Eine weitere Abstraktionsschicht hast du nicht weil trotzdem über $_SESSION ganz normal zugegriffen wird.
Abstraktion war auch das falsche Wort. Wollte eigentlich Wrapper schreiben.

Zitat:
Zitat von Jay
kann jeder User der Zugriff auf den Server hat die Sessiondaten und IDs auslesen. Sessions werden nämlich einfach in einem temporären Verzeichnis als Dateien am Server abgelegt. Durch die Einstellung session.save_path bekommt man den Pfad zum Verzeichnis. Jetzt kann man sich ein einfachs Script schreiben, dass dieses Verzeichnis öffnet die Dateien ausliest und ausliest. Damit ist es ein leichtes eine andere Anwendung am gleichen Server zu knacken.
Kann man nicht alternativ einfach einen eigenen session.save_path setzen?
http://de3.php.net/manual/en/functio...-save-path.php



@MrNiceGuy:
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:50   Nach oben    #7
Jay
Gast
 
Beiträge: n/a
Standard

Zitat:
Kann man nicht alternativ einfach einen eigenen session.save_path setzen?
Dann liegt wieder alles am Filesystem und kann ausgelesen werden, außerdem musst du mal die entsprechenden Rechte besitzen, diese ini einstellung setzen zu dürfen und du brauchst ein entsprechendes schreibbares Verzeichnis, welches du dir auch nicht so einfach anlegen darfst.

Jay
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:55   Nach oben    #8
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.590
Standard

Hm, okay.
Hat eventuell jemand mal ein wenig Beispielcode bzw. kann mir erklären, wie man dann am geschicktesten solch einen Wrapper schreibt?
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 17:59   Nach oben    #9
MrNiceGuy
Erfahrener Benutzer
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 625
Standard

Hmm... Sehr interessant, da hatte ich noch garnicht drüber nachgedacht!? Aber bei meinem Webserver ist es zum Beispiel so, dass jede Domain seinen eigenen Benutzer hat, ich weiß allerdings gerade nicht, wie die Session-Datei im /tmp aussieht, könnte ja sein, dass die sowieso nur lese-rechte auf den Benutzer hat!? Denn sonst könnte man ja auch, wie du es gerade sagtest, Jay, einfach auf die Scripte selber zugreifen und dann hilft dir auch das Schreiben in die DB nicht mehr!?

EDIT: @ben: Die Funktionen serialize() und das Pendant unserialize() sollten die helfen.
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 18:03   Nach oben    #10
Jay
Gast
 
Beiträge: n/a
Standard

Zitat:
EDIT: @ben: Die Funktionen serialize() und das Pendant unserialize() sollten die helfen.
session_decode ist wohl besser.
@Ben
http://at.php.net/session_set_save_handler

Da ist ein Beispiel angeführt. Das verwendet wegen Einfachheit Dateien. Für eine DB müsstest du halt anstatt dateien zu schreiben und zu löschen SQL Queries verwenden

EDIT:
Zur Datei (ganz überlesen
Name: sess_sessionid
Inhalt dürfe so in etwa aussehen wenn $_SESSION['asdf'] auf "jklö" gesetzt ist:
asdf|s:4:"jklö";

Würde man das serialisieren, dann würde das so aussehen
{s:4:"asdf";s:4:"jklö";}

Geändert von Jay (04.06.2006 um 18:12 Uhr).
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 19:26   Nach oben    #11
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.590
Standard

Ich habe soeben gemerkt, dass in meinem neuen Buch ausgiebig auf dieses Thema eingegangen wird.
Ich werde mich da also einmal einarbeiten.
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.06.2006, 19:49   Nach oben    #12
Shin Yoshida
Neuer Benutzer
 
Registriert seit: 20.03.2006
Beiträge: 5
Standard

Hier ein simples, selbsterklärendes Session Handler System.

PHP-Code:
<?php

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

function 
_open()
{
  global 
$_sess_db;

  
$db_user $_SERVER['DB_USER'];
  
$db_pass $_SERVER['DB_PASS'];
  
$db_host 'localhost';
    
  if (
$_sess_db mysql_connect($db_host$db_user$db_pass))
  {
    return 
mysql_select_db('sessions'$_sess_db);
  }
    
  return 
FALSE;
}

function 
_close()
{
  global 
$_sess_db;
    
  return 
mysql_close($_sess_db);
}

function 
_read($id)
{
  global 
$_sess_db;

  
$id mysql_real_escape_string($id);

  
$sql "SELECT data
          FROM   sessions
          WHERE  id = '$id'"
;

  if (
$result mysql_query($sql$_sess_db))
  {
    if (
mysql_num_rows($result))
    {
      
$record mysql_fetch_assoc($result);

      return 
$record['data'];
    }
  }

  return 
'';
}

function 
_write($id$data)
{   
  global 
$_sess_db;

  
$access time();

  
$id mysql_real_escape_string($id);
  
$access mysql_real_escape_string($access);
  
$data mysql_real_escape_string($data);

  
$sql "REPLACE 
          INTO    sessions
          VALUES  ('$id', '$access', '$data')"
;

  return 
mysql_query($sql$_sess_db);
}

function 
_destroy($id)
{
  global 
$_sess_db;
    
  
$id mysql_real_escape_string($id);

  
$sql "DELETE
          FROM   sessions
          WHERE id = '$id'"
;

  return 
mysql_query($sql$_sess_db);
}

function 
_clean($max)
{
  global 
$_sess_db;
    
  
$old time() - $max;
  
$old mysql_real_escape_string($old);

  
$sql "DELETE
          FROM   sessions
          WHERE  access < '$old'"
;

  return 
mysql_query($sql$_sess_db);
}

?>
Shin Yoshida ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 05.06.2006, 03:33   Nach oben    #13
J33d3X
Goldman.de
 
Benutzerbild von J33d3X
 
Registriert seit: 09.10.2005
Ort: Frankfurt am Main
Beiträge: 190
Standard

- wenn man volle Kontrolle über sein Sessionhandling haben will
- Sessionmanagement in Verbindung mit Usermanagement
( xml basierend )

als Ansatz:


session.lib.inc
PHP-Code:
<?php
// {{{ Header
/**
 * session.lib.inc
 *
 * powered by Department-X.de
 * @autor j.mueller@department-x.de
 */
// }}}
error_reporting(E_ALL);


unset(
$_SESSION);


// }}}
// {{{ _properties

$sname    'sid';

$spath    $dir.'sdata/';

$ctimeout time() + 60*60*24*365*10;

$srcurl   $_SERVER['REQUEST_URI'];

$checked  false;

define("COOKIE_PREFIX""smg");

$_level               = array();
$_level['developer']  = 50;
$_level['sysadmin']   = 30;
$_level['mandant']    = 10;
$_level['guest']      = 1;
$_level['freez']      = 0;


$_referer  = isset($_SERVER['HTTP_REFERER'])
           ? 
$_SERVER['HTTP_REFERER']
           : 
'unknow';

$_agent    = isset($_SERVER['HTTP_USER_AGENT'])
           ? 
$_SERVER['HTTP_USER_AGENT']
           : 
'unknow';


require_once(
'XML/Tree.php');
$xml  = new XML_Tree($dir.'xmldb/user.xml');
$
$dir $xml->getTreeFromFile();

for (
$i =0$i count($$dir->children); $i +=1)
{
    if (
strlen($$dir->children[$i]->attributes['name']))
    {
        
$usr[$$dir->children[$i]->attributes['name']]['pass'] = $$dir->children[$i]->attributes['pass'];
        
$usr[$$dir->children[$i]->attributes['name']]['level'] = $$dir->children[$i]->attributes['level'];
        
$usr[$$dir->children[$i]->attributes['name']]['userid'] = $$dir->children[$i]->attributes['userid'];
    }
}


/** is session true */

if (isset($_POST[$sname]) && !empty($_POST[$sname]))
{
    
$_SESSION[$sname] = $_POST[$sname];
}
elseif (isset(
$_GET[$sname]) && !empty($_GET[$sname]))
{
    
$_SESSION[$sname] = $_GET[$sname];
}
else
{
    
$_SESSION[$sname] = isset($_COOKIE[COOKIE_PREFIX.$sname])
                      ? 
$_COOKIE[COOKIE_PREFIX.$sname]
                      : 
false;
}



if (isset(
$_SESSION[$sname]) && strlen($_SESSION[$sname]))
{
    
$username = isset($_COOKIE[COOKIE_PREFIX.'username'])
              ? 
$_COOKIE[COOKIE_PREFIX.'username']
              : 
false;
              
    
$userpass = isset($_COOKIE[COOKIE_PREFIX.'userpass'])
              ? 
$_COOKIE[COOKIE_PREFIX.'userpass']
              : 
false;
    
    if (
true == $username && false == $userpass)
    {
        
/** korrupt */
        
@unlink($spath.$_SESSION[$sname]);
        
setcookie(COOKIE_PREFIX.$sname'', ($ctimeout), '/');
        
setcookie(COOKIE_PREFIX.'username''', ($ctimeout), '/');
        
setcookie(COOKIE_PREFIX.'userpass''', ($ctimeout), '/');
        unset(
$_SESSION);
        
header("location:$srcurl");
    }
    if (
true == $userpass && false == $username)
    {
        
/** korrupt */
        
@unlink($spath.$_SESSION[$sname]);
        
setcookie(COOKIE_PREFIX.$sname'', ($ctimeout), '/');
        
setcookie(COOKIE_PREFIX.'username''', ($ctimeout), '/');
        
setcookie(COOKIE_PREFIX.'userpass''', ($ctimeout), '/');
        unset(
$_SESSION);
        
header("location:$srcurl"