begin process at 2010 03 22 12:33:00
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Class et Objet ( POO )

 > [PHP5]CLASSE DE SESSION

[PHP5]CLASSE DE SESSION


 Information sur la source

Note :
5 / 10 - par 1 personne
5,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Class et Objet ( POO ) Classé sous :poo, classe, session, wraper, securisation Niveau :Initié Date de création :17/06/2007 Date de mise à jour :18/06/2007 13:45:19 Vu :7 832

Auteur : hametsu21

Ecrire un message privé
Site perso
Commentaire sur cette source (25)
Ajouter un commentaire et/ou une note

 Description

Bonjour,
voici une classe qui permet de manipuler les sessions afin de ne pas ré ecrire tous le code si un jour, vous voulez les utiliser différement.
De plus cette classe sécurise en enregistrant dans une variable une marque d'empreinte qu'elle compare à chaque instance et regénère l'id.

Je pense qu'elle n'est pas tout à fait optimiser et j'attends de vous des critiques constructives afin de l'ameliorer...

Source

  • <?php
  • class Session implements ArrayAccess
  • {
  • const SALT_LENGTH = 9;
  • private static
  • $initiated = false,
  • $fingerprint = null;
  • public function __construct()
  • {
  • session_start();
  • $this->check();
  • }
  • private function check()
  • {
  • // prevent session fixation
  • if (self::$initiated == false)
  • {
  • session_regenerate_id();
  • self::$initiated = true;
  • }
  • // prevent session hijacking
  • if (!is_null(self::$fingerprint))
  • {
  • if (self::$fingerprint !== $this->generateHash($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'], self::$fingerprint))
  • {
  • throw new Exception('Votre session est invalide');
  • }
  • }
  • else
  • {
  • self::$fingerprint = $this->generateHash($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']);
  • }
  • }
  • private function generateHash($plain_text, $salt = null)
  • {
  • if (is_null($salt) == true)
  • {
  • $salt = substr(md5(uniqid(mt_rand(), true)), 0, self::SALT_LENGTH);
  • }
  • else
  • {
  • $salt = substr($salt, 0, self::SALT_LENGTH);
  • }
  • return $salt . sha1(strrev($salt) . $plain_text);
  • }
  • public function offsetExists($offset)
  • {
  • return isset($_SESSION[$offset]);
  • }
  • public function offsetSet($offset, $value)
  • {
  • $_SESSION[$offset] = $value;
  • }
  • public function offsetUnset($offset)
  • {
  • if (isset($_SESSION[$offset]))
  • {
  • unset($_SESSION[$offset]);
  • }
  • }
  • public function offsetGet($offset)
  • {
  • if (isset($_SESSION[$offset]))
  • {
  • return $_SESSION[$offset];
  • }
  • return null;
  • }
  • public function __destruct()
  • {
  • session_write_close();
  • }
  • }
  • ?>
<?php

class Session implements ArrayAccess
{
	const SALT_LENGTH = 9;
	
	private static
		$initiated   = false,
		$fingerprint = null;
		
	public function __construct()
	{
		session_start();
		$this->check();
	}
	
	private function check()
	{
		// prevent session fixation
		if (self::$initiated == false)
		{
			session_regenerate_id();
			self::$initiated = true;
		}

		// prevent session hijacking
		if (!is_null(self::$fingerprint))
		{
			if (self::$fingerprint !== $this->generateHash($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'], self::$fingerprint))
			{
				throw new Exception('Votre session est invalide');
			}
		}
		else
		{
			self::$fingerprint = $this->generateHash($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']);
		}
	}
	
	private function generateHash($plain_text, $salt = null)
	{
		if (is_null($salt) == true)
		{
			$salt = substr(md5(uniqid(mt_rand(), true)), 0, self::SALT_LENGTH);
		}
		else
		{
			$salt = substr($salt, 0, self::SALT_LENGTH);
		}
		
		return $salt . sha1(strrev($salt) . $plain_text);
	}

	public function offsetExists($offset)
	{
		return isset($_SESSION[$offset]);    
	}
	
	public function offsetSet($offset, $value)
	{
		$_SESSION[$offset] = $value;
	}
	
	public function offsetUnset($offset)
	{
		if (isset($_SESSION[$offset]))
		{
			unset($_SESSION[$offset]);
		}
	}
	
	public function offsetGet($offset)
	{
		if (isset($_SESSION[$offset]))
		{
			return $_SESSION[$offset];
		}
		
		return null;
	}

	public function __destruct()
	{
		session_write_close();
	}
}

?>

 Conclusion

J'utilise une classe 'Registry' me permettant de n'avoir une seule intance de l'objet. Peut être faudrait-il rajouter une méthode singleton pour l'utiliser...


 Historique

18 juin 2007 13:45:19 :

 Sources du même auteur

Source avec Zip [PHP5]CLASSE DE TEMPLATE PHP AVEC CACHE
Source avec Zip SYSTEME DE NOUVELLE POO
Source avec Zip Source avec une capture [PHP5]GENERATION DE FLUX RSS

 Sources de la même categorie

Source avec Zip CLASSE TABLE HTML DYNAMIQUE par LDDL
Source avec Zip GÉNÉRATEUR DE COUCHE DAO POUR SITE WEB À PARTIR D'UNE BASE D... par alexfool
Source avec Zip [PHP5.2] CLASSE PDO par hornetbzz
Source avec Zip POO - LOGGING PACKAGE par Waredan
POO - OBJECT CLASS par Waredan

 Sources en rapport avec celle ci

Source avec Zip [PHP5.2] CLASSE PDO par hornetbzz
Source avec Zip CLASSE SIMPLE DE GESTION DE FICHIERS par alexarbitre
Source avec Zip EXÉCUTER DES REQUETE STYLE SQL SUR UN ARRAY par prince418
Source avec Zip [POO][PHP5]UN SITE MULTILANGUE VIA XML par destinyfr
Source avec Zip CLASSE DATETIME ÉTENDUE PHP 5.2 par nautilus99

Commentaires et avis

Commentaire de amezghal le 17/06/2007 12:27:48

salut
-pour les tests de ce genre: if(isset($this->fingerprint) == false
il suffit d'utiliser:if(!isset($this->fingerprint))
-idem pour:if($x==true) il suffit:if($x)
-pour la géneration des nombres aléatoire utilise plutot la fonction mt_rand()( qui initialise le générateur automatiquement des php 4.2.0)


Commentaire de kankrelune le 17/06/2007 12:45:33

Salut...

Tout d'abord ton "fingerprint" ne sert strictement à rien là... sinon...

http://fr2.php.net/manual/fr/function.session-set-save-handler.php

@ tchaOo°

Commentaire de hametsu21 le 17/06/2007 18:30:32

ah bon ? et pourquoi cela ?
Si la variable enregistré dans la classe n'est pas égale à celle enregistré dans les sessions, cela signifie que la session a été détourné... donc une exception est levée et bloque l'accés. Je ne vois pas pourquoi ça ne "sert strictement à rien". Pourrais-tu plus développer afin que je comprenne mieux ton point de vue ?

Commentaire de coucou747 le 17/06/2007 19:00:46

le vol de sessions, c'est pas une faille courante... comment tu peux avoir le md5 de microtime du moment ou le gars que tu veux voler s'est connecte ?

Commentaire de hametsu21 le 17/06/2007 20:05:40

En faite, c'est après avoir lu cette article : http://phpsec.org/projects/guide/4.html que je me suis  mis à ajouter le "fingerprint" dans ma class de session. Car rappelons-le, cette class n'a pas pour but d'enregistrer nos sessions dans une base de donnée ou tout autre mode d'enregistrement de donnée (texte, etc..) mais d'eviter de se servir directement dans nos scripts de la variable super global "$_SESSION" et ainsi, si par la suite, nous voulons coder différement, il suffira de modifier qu'un fichier...
Ensuite, le fingerprint est venu se greffer afin d'ajouter un plus en matière de sécurité !

> Krankrelune, il sert à rien de la façon que je l'enregistre et le compare, ou sert à rien tout court ?

> Coucou747, j'ai pas tout compris, pourrais-tu reformuler ta question s'il te plait ?

A+ ! ;)

Commentaire de webdeb le 17/06/2007 22:07:16

Pourquoi ne pas vouloir utiliser $_SESSION ? Cette superglobale est faite pour ça, tout comme$_GET, $_POST, $_COOKIE, $_REQUEST, $_SERVER...

Ta classe ajoute une surcouche aux sessions qui n'est pas spécialement utile. Il vaut mieux utiliser directement les sessions. Leur mécanisme est si simple et efficace à mettre en oeuvre.

Commentaire de malalam le 18/06/2007 09:28:44 administrateur CS

Hello,

je trouve aussi que ta classe est légère. Une remarque tout bête : je fais comment, avec ta classe, une variable de session sous forme de tableau multidimensionnel ?
Je ne fais pas.
Clairement, de nos jours, pour réécrire une classe de session, il FAUT passer par la SPL et notamment arrayAccess.

Commentaire de Naixn le 18/06/2007 09:50:37

Malalam > $session = new Session; $session->bla = array(1, 2); ? Non ?
Ou alors j'ai mal compris ta question...

Commentaire de hametsu21 le 18/06/2007 10:01:04

Tu entend par là, d'enregistrer dans la session un tableau à plusieurs dimensions ?

$session = new Session();
$session->test=array('test' => array('test' => array('test' => array('test'))));
print_r($session->test);

non ?

Je pensais que ArrayAccess ne supportait pas les tableaux multidimensionnelles après avoir lu quelques articles sur cette interface (exemple : http://blog.plumbr.com/3-implement-arrayaccess-vous-connaissez ). En réalité le problème a été fixé et il gère effectivement les tableaux, c'est donc un moyen assez performant en effet pour réécrire une classe de session :)

Ensuite, au niveau du fingerprint ? Comment aurais tu fais toi, Malalam ?

Commentaire de malalam le 18/06/2007 12:58:43 administrateur CS

Ok pour
$session->test=array('test' => array('test' => array('test' => array('test'))));
Et si ENSUITE, plus tard, je veux ajouter encore un élément $ $_SESSION['test']['test'] par exemple ? En gardant les précédents ?

Commentaire de hametsu21 le 18/06/2007 13:48:56

Source mis à jour par rapport aux améliorations suggérés.

Malalam, j'ai peut être dis une connerie :D

l'interface ArrayAcces ne permet pas de faire ce que tu dis, de même que la version précédente de ma classe de session.

exemple :

$session = new Session();
$session['test'] = array();
$session['test']['bidule'] = 'truc';
$session['test']['bidule']['machin'] = 'chouette';

print_r($session);

résultat :

Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in X on line X

Ou peut être, j'utilise mal l'interface o_O ?

Commentaire de FhX le 18/06/2007 13:54:44

class session {

public function __get($var) {
  return $_SESSION[$var];
}
public function __set($var, $val) {
  $_SESSION[$var] = $val;
}

}

$session = new session;
$session->montableau[10][20][30] = array('x');
$session->mon_autre_tableau[10] = $session->montableau[10][20][30];
echo $session->mon_autre_tableau[10];

Où est le problème ?

Commentaire de hametsu21 le 19/06/2007 08:36:49

Et si tu utilises l'implantation d'ArrayAccess, tu fais le même pour assigner une nouvelle valeur tu créer un nouveau tableau avec tes anciennes valeurs et tes nouvelles. C'est un peu moche :p mais ça fonctionne...

À par ça, niveau sécurité (session fixation et hijacking), est-ce bien mis en place avec les attributs (static) et la manière dont fonctionne la méthode check() ? Actuellement, uniquement Kankrelune et Coucou747 ont donné leur avis sur le sujet.

Tchô !

Commentaire de malalam le 19/06/2007 09:32:55 administrateur CS

Hello,

sauf que, Fhx, ça ne marche pas ton code.
$session->mon_autre_tableau[10] est pris pour une variable, pas un tableau, via les setter. Fais un print_r dessus.

Il faut implémenter arrayAccess avec d'autres interfaces/classes, dont recursiveAIterator.

Commentaire de hametsu21 le 19/06/2007 10:02:40

Tu voulais dire RecursiveIterator ? Avec un "A", je ne trouve rien...

Commentaire de malalam le 19/06/2007 12:26:33 administrateur CS

Oui, c'est ce que je voulais dire :-)

Commentaire de FhX le 21/06/2007 09:00:58

Ah vi en effet :p

Commentaire de hametsu21 le 22/06/2007 16:59:27

Mouais, j'ai pas tellement réussis :/

Commentaire de malalam le 25/06/2007 12:22:51 administrateur CS

Bon allez, en réalité c'est très simple car tout est déjà fait :

<?php
$a = new RecursiveArrayIterator();
$a['test']['bla'] = 2;
echo $a['test']['bla'], '<br />';
echo gettype ($a['test']);
?>

Commentaire de hametsu21 le 25/06/2007 12:42:12

donc faudrait juste que la classe Session extends RecursiveArrayIterator ?

Commentaire de hametsu21 le 25/06/2007 14:33:31

J'ai étendu ma classe Session avec RecursiveArrayIterator, et ça ne marche pas !

$session = new Session();
$session['test'] = array('un', 'deux', 'trois');
$session['test'][] = 'quatre';
print_r($session['test']);

retourne toujours : Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in /Users/quentinberlemont/Sites/session.php on line 83

Commentaire de malalam le 25/06/2007 15:13:23 administrateur CS

Ca chez moi, ça marche :

<?php
$a = new RecursiveArrayIterator();
$a['test']['bla'] = 2;
echo $a['test']['bla'], '<br />';
echo gettype ($a['test']), '<br />';
echo gettype ($a), '<br />';
$a['tab'] = array (1,2,3);
$a['tab'][] = 4;
print_r ($a['tab']);
?>

Quelle version de PHP5 as-tu ?

Commentaire de hametsu21 le 25/06/2007 16:37:17

Oui, je suis d'accord mais comment faire le lien entre ça et ma source ?

Commentaire de malalam le 25/06/2007 18:20:38 administrateur CS

Il faudrait que je vois ton code et la manière dont tu l'as implémenté, dans ce cas, pour t'aider.

Commentaire de hametsu21 le 25/06/2007 20:52:53

J'utilise PHP 5.1.6, ma source actuellement est posté ici, pour pouvoir utiliser des tableaux à plusieurs dimensions, j'ai étendu ma classe par RecursiveArrayIterator, et me suis contenté de tester comme cela :
$session = new Session();
$session['test'] = array('un', 'deux', 'trois');
$session['test'][] = 'quatre';
print_r($session['test']);
Ce qui me provoque une erreure...
Il faut donc manipuler les classes et rajouter certaines méthodes, mais c'est plutôt flou tout ça :p

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Session : prob d'ajout de données [ par DarkCid ] Yaoh !voilà pour faire mon panier virtuel, j'utilise des sessions. Je mets bien le session_start() ; en début de code et j'appelle cette fonction pour php session_start [ par regis62 ] Bonjour.je suis un débutant en php et j'ai un probléme.Dans la page acces_eleve un éléve se connect (grace à des formulaires).Dans la page requete_ele passer une instance d'une classe par les sessions [ par hybride11 ] Bonjour ,  dans une application qui comporte plusieurs fichiers *.php qui seront appelés à un moment donné dans l'appli, est il possible de faire pass [POO] Une classe dans une classe [ par Mrreivax ] Bonsoir.Et bien voila. J'ai créé une classe de gestion des images.J'ai par la suité créé une autre classe de gestion de banières.Mais, cette dernière Probleme POO [ par cedriclomb ] Bonjour,Aujourd'hui au programme casse tete chinois ! :DVoila j'ai une classe B qui est une extends de Aun objet $b=new B;et ensuite $b-&gt;loadModule $_SESSION a un comportement bizarre [ par CyberP ] Bonjour,Mon site Internet comporte une partie administration qui utilise les sessions pour vérifier que quelqu'un est authentifié.Lorsqu'on s'identifi Classe abstraite DataBase [ par codefalse ] Hello les gens :)J'ai développé un petit ensembles de classes en php 5, et j'aimerai votre avis :)Je ne vous le cacherai pas, je me suis énormément ba prob de header() [ par soussan ] sltj"ai un formulaire de validation de login et passe après validation ca doit rediriger vers une autre page concernant les clients seulementtt le tra set_cookie de 1&1 à ovh [ par Merlin69100 ] Bonjour,Suite à la migration de 1&amp;1.com a 10gp (ovh)J'ai le message d'erreur suivant, pouvez-vous m'aider Merci d'avance![CODE]Fatal error: Call t


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,655 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales