developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Opened 13 years ago

Closed 13 years ago

Last modified 12 years ago

#354 closed new feature (fixed)

jSession : alternative storage engines for sessions (files and Dao)

Reported by: Julien Owned by: laurentj
Priority: normal Milestone: Jelix 1.0 RC1
Component: jelix:core Version: 1.0 beta 3.1
Severity: normal Keywords:
Cc: Blocked By:
Blocking: Documentation needed: no
Hosting Provider: Php version:

Description

Français

jSession permet de stocker les sessions de façon personnalisée, en fonction de paramètres déclarés dans app/var/config/defaultconfig.ini.php :

Stockage dans un répertoire

Il n'est pas toujours prudent de stocker les sessions dans le répertoire par défaut prévu par l'hébergeur, car celui-ci peut être accessible de tout le monde, comme /tmp/ par exemple.

Pour utiliser jSession avec un répertoire personnalisé :

[sessions]
storage = "files"
files_path = "app:var/sessions/"

NB : les mots clés app: et lib: sont reconnus.

Stockage dans la base de données

On peut avoir besoin de stocker les données de session en base de données, par exemple pour permettre un partage aisé en cas de répartition de charge entre plusieurs serveurs web.

Pour utiliser jSession avec un Dao :

[sessions]
storage = "dao"
dao_selector = "jsession~session"
dao_db_profile = ""

NB : un dao est fourni par défaut, c'est jsession~session. Il se trouve dans jelix-modules/jsession/daos/.
La structure de table pour ce DAO est :

CREATE TABLE `sessions` (
  `id` varchar(64) NOT NULL,
  `creation` datetime NOT NULL,
  `access` datetime NOT NULL,
  `data` text NOT NULL,
  PRIMARY KEY  (`id`)
) DEFAULT CHARSET=utf8;

English

jSession provides alternative storage engines. Configuration is done in app/var/config/defaultconfig.ini.php :

File storage

Storing session files in default path may not be a good idea, as that path is often worldwide readable/writable, like /tmp/ for example.

To make jSession store sessions in your own defined path :

[sessions]
storage = "files"
files_path = "app:var/sessions/"

NB : app: and lib: keywords are converted.

Database storage

You may need to store your sessions in data, for example when you are doing load-balancing with multiple front servers.

jSession uses jDao :

[sessions]
storage = "dao"
dao_selector = "jsession~session"
dao_db_profile = ""

NB : a default dao is provided : jsession~session. It's located in jelix-modules/jsession/daos/.
The corresponding DB creation request :

CREATE TABLE `sessions` (
  `id` varchar(64) NOT NULL,
  `creation` datetime NOT NULL,
  `access` datetime NOT NULL,
  `data` text NOT NULL,
  PRIMARY KEY  (`id`)
) DEFAULT CHARSET=utf8;

Attachments (2)

jSession.patch (10.3 KB) - added by Julien 13 years ago.
Patch corrigé : le profil jDb n'était pas pris en compte lors de l'enregistrement des donées de session
jSession.2.patch (9.9 KB) - added by Julien 13 years ago.
patch modifié, avec session_write_close(), sans hack de jDb

Download all attachments as: .zip

Change History (13)

comment:1 Changed 13 years ago by Julien

Laurent, petite remarque sur le changement au niveau de jDbConnection.

Au moment d'enregistrer la session en base de données, tous les objets sont déja détruits (ça explique d'ailleurs le stockage du fichier de config dans jSession pour pouvoir recréer gJconfig).

Bref, la connexion SQL a été fermée avant d'enregistrer les données de session.

J'ai donc besoin de pouvoir la réouvrir à partir de jSession::dao_write(), d'où la méthode publique reconnect().

Julien

comment:2 Changed 13 years ago by laurentj

  • Milestone Jelix 1.0 RC1 deleted
  • Priority changed from high to normal

Changed 13 years ago by Julien

Patch corrigé : le profil jDb n'était pas pris en compte lors de l'enregistrement des donées de session

comment:3 Changed 13 years ago by laurentj

  • Milestone set to Jelix 1.0 RC1

Plusieurs points à revoir sur ce patch :

+++ build/manifests/jelix-lib.mn	(working copy)
@@ -260,7 +260,10 @@
 cd lib/jelix-modules/jauth/zones
 ! loginform.zone.php
 
+cd lib/jelix-modules/jsession/daos
+  session.dao.xml
 
+
  • mettre le fichier dao dans le module jelix directement
  • ligne ajoutée en trop
+++ lib/jelix-modules/jsession/daos/session.dao.xml	(revision 0)
+        <property name="creation" fieldname="creation" datatype="date" insertpattern="NOW()" required="true"/>

Je pense que cette property devrait avoir un updatepattern="" (rien à l'update...)

+++ lib/jelix/db/jDbConnection.class.php	(working copy)
@@ -68,6 +68,7 @@
     function __destruct(){
         if($this->_connection !== null){
            $this->_disconnect ();
+           $this->_connection = null;
         }
     }

Est ce vraiment utile de mettre à null ? à priori, on est ici dans le destructeur, donc de toute façon cette propriété va être détruite dès la fin du destructeur.

+    public function reconnect(){

Pas sûr de l'utilité de cette méthode. Je n'ai pas trop compris son rôle. Et de toute façon inutile si l'histoire du session_write_close fonctionne (Voir ci-dessous).

+++ lib/jelix/core/jCoordinator.class.php	(working copy)

+        // reference the config file in jSession, because gJConfig no longer exists when the session data is written, and we need it for Dao storage
+        jSession::$jConfigFile = $configFile;

Si j'ai bien compris, la session est fermée à la fin de la page, après avoir détruit toutes les variables globales. Pourquoi n'essaierais-tu pas de faire un session_write_close() à la fin de la méthode process() ? Je pense alors que tout serait encore en place, donc pas besoin de recharger le fichier de config &cie (ce qui est gourmand en ressource), pas besoin de ces hacks sur jDbConnection.

+++ lib/jelix/core/jSession.class.php	(revision 0)

Attention dans ce fichier, il y a des caractères tabulation au lieu d'espaces. Corriger ces problèmes d'indentation. Supprimer aussi les espaces qui trainent en fin de ligne.

+    public static function dao_open ($save_path, $session_name) {

Utiliser plutôt le nommage habituel de Jelix pour les méthodes : daoOpen, daoClose etc...

+        if(!isset($gJConfig->sessions)){
+            session_start();
+            return true;
+        }

Inutile, la section sessions existe toujours, vu qu'elle est dans le defaultconfig.ini.php du core (ce fichier étant fusionné avec le defaultconfig.ini.php de l'appli lors de la lecture de la config)

+	    global $gJConfig;
+	    
+	    $gJConfig = jConfig::load(self::$jConfigFile);
+	
+	    if(isset(self::$_params['dao_db_profile']) && self::$_params['dao_db_profile']){
+	        $cnx = jDb::getConnection(self::$_params['dao_db_profile']);
+        }
+        else{
+            $cnx = jDb::getConnection();
+        }
+	    $cnx->reconnect();

À supprimer si l'histoire du session_write_close() fonctionne.

+        $dao = self::_getDao();
+		$dao->delete($id);

On peut simplifier en

self::_getDao()->delete($id);
+        $dao = self::_getDao();
+        $dao->deleteExpired($date->toString(jDateTime::BD_DTFORMAT));

Idem que précédement.

Ce serait bien, si tu avais le temps, de rajouter quelques tests unitaires sur les méthodes dao*.

Je pense que ça ira quand tout sera corrigé ;-).

Changed 13 years ago by Julien

patch modifié, avec session_write_close(), sans hack de jDb

comment:4 Changed 13 years ago by Julien

Laurent, je viens de poster le patch modifié.

Effectivement, ça marche bien en utilisant la fermeture explicite de session à la fin de la méthode process() du coordinateur.

Du coup, j'ai laissé jDb tranquille ;)

NB : j'ai encapsulé session_write_close() dans jSession::end(), au cas où on aurait un jour autre chose à faire à la fermeture de session. A ce stade, ce n'est pas vraiment justifié, mais sait-on jamais. Je pense que les perfs n'en sont pas réellement affectées. Et puis ça garde la cohérence avec jSession::start().

J'ai suivi tes autres demandes de modif aussi, je crois que tout est bon à présent.

Note : il n'y avait pas de section "sessions" dans lib/jelix/core/defaultconfig.ini.php, donc je l'ai rajouté, et j'y ai déplacé la directive shared_session.
J'ai bien entendu modifié les endroits où cette directive est lue dans Jelix, soit un seul endroit : le constructeur du coordinateur.
Je me demande d'ailleurs si d'une façon ou d'une autre, les 3 lignes suivantes

//make sure that the session cookie is only for the current application
if(!$gJConfig->sessions['shared_session'])
    session_set_cookie_params ( 0 , $gJConfig->urlengine['basePath']);

ne devraient pas être déplacées dans jSession::start().

Pour les tests unitaires, je verrai plus tard (manque de temps), mais ne les attends pas forcement pour inclure le patch ;)

Julien

comment:5 Changed 13 years ago by laurentj

  • Resolution set to fixed
  • Status changed from new to closed

Patch ok. Inclus dans le trunk. Merci pour cette contribution !

comment:6 Changed 12 years ago by laurentj

  • Documentation needed set

comment:7 Changed 12 years ago by Julien

Ok, idem dans le wiki

j'ajouterai une nouvelle section dans "Composants de jelix"

comment:8 Changed 12 years ago by laurentj

j'ajouterai une nouvelle section dans "Composants de jelix"

Ça marche. D'ailleurs, pour la doc, si tu pouvais la faire directement en anglais (mais c'est pas une obligation..)

comment:9 Changed 12 years ago by Julien

Tu veux dire en + du français je pense, dans le manuel anglais ?

pas de prob, même s'il faudra sans doute repasser sur mon anglais ;)

comment:10 Changed 12 years ago by Julien

Hello,

apparemment qqun avait commencé la doc :

http://jelix.org/articles/manuel/session

mais ce n'est plus d'actualité (mauvais emplacement du DAO, fonctionnalité du patch #417)

Je vais donc mettre ça à jour.

comment:11 Changed 12 years ago by laurentj

  • Documentation needed unset
Note: See TracTickets for help on using tickets.