IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Gestion des sessions en BDD : régénérer l'identifiant


Sujet :

Langage PHP

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut Gestion des sessions en BDD : régénérer l'identifiant
    Bonjour à tous,

    Dans l'esprit du gestionnaire de session que j'ai déjà réécrit (pour utiliser un stockage bdd et surtout pour des fontionnalités de gc bien spécifiques).

    Lors de cette réécriture, j'ai été bien content de trouver dans la doc officielle, le code initial, en php, des différentes fonctions du gestionnaire. Ces fonctions initiales m'ont servi de support pour écrire mes fonctions personnalisées.

    Je souhaiterais faire la meme chose pour session_regenerate_id()

    Merci par avance.

  2. #2
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Théoriquement il y a rien à faire de plus que d'appeler la fonction.

    Toujours théoriquement, ça déclenchera les fonctions que tu as créé et défini dans le session_set_save_handler(), et la session aura un nouvel ID tout en conservant les même données, tout ça peu importe que les sessions soient dans des fichier ou Bdd.

    Fait un essai.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut
    Salut,

    Oui, tu as raison, sauf j'ai besoin de fonctionnalités spécifiques, légèrement différentes que le simple appel des fonctions que j'ai créées et du coup, j'ai besoin de réécrire cette fonction pour la personnaliser

    Merci

  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    sauf j'ai besoin de fonctionnalités spécifiques, légèrement différentes que le simple appel des fonctions que j'ai créées et du coup, j'ai besoin de réécrire cette fonction pour la personnaliser
    Dans cette condition, il sera difficile de t'aider.
    On faite, on ne sait pas se qu'il se cache derrière cette fonction, du moins, moi j'en sais rien.
    C'est à mon sens la même chose qu'un session_start().

    D'ailleurs, je ne vois pas vraiment l'intérêt de réécrire cette fonction.
    Soit on a quelque chose à faire avant, soit après avoir régénérer l'ID, car cette fonction y fait pas grand chose finalement, juste changer l'ID de la session, car elle reste la même.
    Donc tu peux très bien créer ta propre fonction du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    my_session_regenerate_id() {
        // code à faire avant
        session_regenerate_id();
        // code à faire après
    }
    Ou alors, c'est dans les fonction session_write() ou session_read() (que tu dois avoir) où il faudrait intervenir, j'en sais rien.


    Si tu en disais un peu plus ce que tu qualifie de "fonctionnalités spécifiques".

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut
    Alors je vais vous en dire un peu plus

    Tout d'abord, (une partie de) ce que fait le regenerate_id. Elle ne se contente pas de faire un session_start mais elle fait également un session_destroy
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $temp=$_SESSION;
    session_destroy();
    session_start();
    $_SESSION=$temp;
    Pour le contexte et mes besoin, il s'agit de la gestion d'un panier. Dans ce dernier, l'internaute peut uploader des fichiers en rapport avec sa commande.
    Tant que le panier n'est pas finalisé (payé) les fichiers restent sur le serveur en tant que "panier temporaire". Ils deviennent définitifs lorsque le panier est payé

    En cas d'abandon de panier et surtout d'expiration/destruction de session, il ne faut pas se contenter de supprimer les données de session. S'il reste à ce moment des fichiers de "panier temporaire", il faut inclure leur suppression dans le garbage collector. Sinon on aurait des orphelin fichiers qui s'accumulent. Orphelins car ils ne sont plus associés à rien. Ni un panier finalisé, ni un panier en cours de creation.

    Cette partie est faite, j'ai réécrit le gestionnaire de session pour que le GC appelle la fonction destroy et que la fonction destroy fasse le menage dans les fichiers lorqu'elle supprime une session. Tout est ok et tout fonctionne

    Le probleme est le regenerate_id. En effet, lorsque l'internaute s'identifie à son compte client, je lance un regenerate_id, afin d'éviter les vols de session.
    Comme ce dernier fait un destroy sur la session en cours avant d'en creer une nouvelle, les fichiers uploadés par l'internaute sont supprimés.

    D'où mon problème

    Si je n'ai pas réussi à être clair, n'hésitez pas à me demander plus de détails.

    En fait, depuis hier soir j'ai fini par trouver une solution qui fonctionne mais ne me semble pas optimale.

    Voici ce que j'ai fait. Dans ma fonction personnalisée destroy, je mets un parametre $cleanFiles que je place par défaut à false
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function sessionDestroy($cleanFiles=false) {
    Ainsi, par défaut mon destroy ne supprime pas les fichiers uploadés. Lorsque le regenerate_id se lance, je ne perds pas mes fichiers.
    Par contre dans ma fonction gc personnalisées, j'appelle sessionDestroy avec cleanFiles à true
    Ainsi, lors de l'expiration de la session, le ménage a bien lieu

    Qu'en pensez vous ?

  6. #6
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Et bien ce ne serait pas un session_regenerate_id() qu'il faudrait faire, mais un session_recreate().
    En tout cas c'est ce que tu tente de refaire à mon avis.

    En cas d'abandon de panier et surtout d'expiration/destruction de session, il ne faut pas se contenter de supprimer les données de session. S'il reste à ce moment des fichiers de "panier temporaire", il faut inclure leur suppression dans le garbage collector. Sinon on aurait des orphelin fichiers qui s'accumulent. Orphelins car ils ne sont plus associés à rien. Ni un panier finalisé, ni un panier en cours de creation.
    Là je ne pige pas trop.
    Si la session vient à expirer, TOUTE la session DOIT être détruite, sinon, ça n'a plus de sens.
    Si après cette action tes données ne sont plus cohérentes, alors c'est la gestion du panier qui serait mal goupillée quelque part.
    Enfin, c'est mon raisonnement.

    Faudrait peut être voir plus en détails les éventuels fichiers que tu considère orphelin (et que tu aurais).
    Pour les fichiers uploadés avant de s'identifier, je ne comprends pas.
    Comment un utilisateur peu à la fois uploader des fichiers et s'identifier en même temps.
    Théoriquement ça devrait être 2 étapes différentes, 2 actions différentes, non ?
    Peut être qu'il te manquerais des informations concernant ces fichiers uploadés dans la session (comme leur nom par exemple).
    Ou alors, peut être faudrait il faire identifier la personne avant de lui proposer d'uploader quoi que ce soit. ?


    En tout cas, je me dis qu'il ne faudrait peut être pas fracasser la gestion des sessions pour résoudre un problème qui ne serait pas directement lié à ça (indirectement, surement).
    Je ne sais si tu me suis ?


    Comme ça au feeling, je dirais donc qu'il faudrait quelque chose au niveau de la session, donc qui stockerait le nom des fichiers uploadés et associés.
    Ensuite, lorsque tu recrée la session, il faudrait aussi changer la date de ces fichiers en question (mettre la même date que la session).
    En somme, on reconduit ces fichiers, comme pour la session.

    Ensuite, pour la destruction des fichiers uploadés qui normalement seraient expirés (comme pour les sessions), et bien les détruire dans le _gc, en se basant sur leur date (fonction filemtime)
    Tu connais la durée d'expiration, elle équivaut à session.gc_maxlifetime (ou celui que tu as redéfini).
    Idem pour le _destroy() normalement.
    Ne sera supprimé QUE ceux qui seront expirés (théoriquement).


    Je ne sais si c'est ce que tu recherche.

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut
    J'ai mal du m'exprimer car le gestionnaire que j'ai écrit inclus toutes tes remarques

    Voici le scénario de navigation:
    1 Parcours les pages sans être loggué => il y a une session qui est créée
    2 Ajout des articles au panier => ils sont mémorisés en session
    3 Consultation du panier/upload les fichiers associés aux articles ajoutés => il faut d'identifier
    4 Upload des fichiers dans le panier => les fichiers sont stockés sur le disque du serveur, associés au panier non encore validé, la liste des fichiers (noms) est mémorisée en session.

    Si à se stade la session expire, on perd la liste des fichiers (en session) mais les fichiers sont toujours sur le disque du serveur. C'est ça que j'appelle orphelins.
    C'est pour ça que j'ai réécrit le session_destroy pour qu'au moment de la suppression des données de session, il supprime également les fichiers uploadés.
    Ca, c'est fait, ça fonctionne. Le comportement est donc ok à ce niveau

    Ce qui me posait probleme. C'est si jamais l'internaute, apres s'etre identifié et avoir uploadé, cliquait sur le lien déco du site (à ce moment je ne détruit pas la session, je ne détruit pas son panier, je me contente de détruite l'id du l'utilisateur connecté. On se retrouve en étape 2. Il existe un panier, l'utilisateur n'est pas logué et s'il veut aller plus loin, il doit s'identifier.

    Dans ce cas précis (cad ajout produit, identification, upload, deconnexion, ré-identification) le regenerate_id lançait un session_destroy et donc supprimait non pas le panier puisque les données de session sont conservées mais supprimait les fichiers précédement uploadés puisque c'est le ménage que fait ma session_destroy personnalisée.

    Du coup, quand l'internaute se réidentifie, il gardait son panier mais devait réuploader ses fichiers

    Ps: Peux tu m'en dire plus sur le session_recreate() ? Car cette fonction ne semle pas connue dans la doc php:
    http://fr2.php.net/manual/en/ref.session.php

    Merci

  8. #8
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Peux tu m'en dire plus sur le session_recreate() ? Car cette fonction ne semle pas connue dans la doc php
    A ben, je croyais que ça y était
    Du coup, on y fait la même chose pour ainsi dire.

    De mon coté, j'y est donc le même principe que le tiens, mais comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        public function recreate() {
            session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy', '_sess_gc');
            if (isset($_COOKIE[$this->_name])) {
                $this->setCookie($this->_name, '', time()-43200, $this->getCookieParameters('path'), $this->getCookieParameters('domain'));
            }
            $_SESSION = array();
            $this->destroy();
        }
    Si tu as déjà les noms des fichiers sur le serveurs, alors ces fichiers ne sont plus si orphelins que ça.

    Ne se pose que le problème de leur destructions.
    Mais comme je l'ai proposé auparavant (pas sûr que tu ais eu le temps de tout lire), mais se baser sur la date des fichiers est théoriquement un bon moyen de le faire.
    Faut juste prendre la précaution de reconduire la date quand tu recrée à nouveau la session.
    Enfin, c'est une idée

  9. #9
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    A coté de ça, vu que tu gère les sessions dans la Bdd et que ces fichiers seraient aussi directement liés, peut être faudrait il créer une table pour ça (genre fichiers_upload_temp), un couple session_id | nom_fichiers.

    Ensuite, le _gc s'occuperait à récupérer les noms des fichiers liés aux sessions à détruire pour justement détruire les fichiers orphelins, et ensuite supprimer les lignes en question.

    En tout cas, la destruction des sessions sont totalement liés à leur date d'expiration.
    Du coup, il me semble normal que la destruction de ces fichiers (orphelins) soient aussi basé sur une date (leur date de création ou de dernière mise à jour).

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut
    Mais encore une fois, la destruction des fichiers en même temps que la destruction de la session, c'est une affaire réglée
    Depuis mon premier post, le problème n'a jamais été là

    Le problème vient du fait que lorsque je lance un regenerate_id, ça lance implicitement la destruction de la session pour en créer une nouvelle et du coup, ça m'efface les fichiers uploadés

  11. #11
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Le problème vient du fait que lorsque je lance un regenerate_id, ça lance implicitement la destruction de la session pour en créer une nouvelle et du coup, ça m'efface les fichiers uploadés
    Justement, j'ai jamais dis qu'il fallait détruire les fichiers uploadés.
    Que je sache, c'est toi qui a rajouter des codes qui suppriment ces fichiers dans le destroy(), non ?

    Tes fichiers uploadés devraient théoriquement être détruits que lorsque la fonction _gc sera exécutée, mais pas dans le destroy().
    Ce qui serait le plus simple.

    Ou alors, il faudrait voir si tu as moyen de rajouter un paramètre à cette fonction destroy(), comme un booléen.
    Par défaut (true), on détruit tout : session + fichiers
    Cependant, lorsque tu appelle la fonction destroy() au moment du login, faut mettre false (on détruit juste la session, on conserve les fichiers uploadés).

  12. #12
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut

    Regarde ce que j'avais déja écrit dans mon post de 09h23:

    En fait, depuis hier soir j'ai fini par trouver une solution qui fonctionne mais ne me semble pas optimale.

    Voici ce que j'ai fait. Dans ma fonction personnalisée destroy, je mets un parametre $cleanFiles que je place par défaut à false
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function sessionDestroy($cleanFiles=false) {
    Ainsi, par défaut mon destroy ne supprime pas les fichiers uploadés. Lorsque le regenerate_id se lance, je ne perds pas mes fichiers.
    Par contre dans ma fonction gc personnalisées, j'appelle sessionDestroy avec cleanFiles à true
    Ainsi, lors de l'expiration de la session, le ménage a bien lieu

    Qu'en pensez vous ?

  13. #13
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Regarde la doc comment cette fonction est construite : http://fr2.php.net/manual/fr/functio...ve-handler.php
    Le 1er paramètre est l'ID de la session, chose que tu ne tiens pas compte, c'est un booleen que tu mets.
    D'ailleurs, je ne vois pas comment tu parviens à supprimer la session avec un booleen.

    Mise à par ça, il faudrait voir si tu peux rajouter ce booleen en 2ème paramètre, et l'exploiter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    sessionDestroy($session_id, $clean = true) {
        // Code qui supprime la session
        ... etc ...
        // On supprime les fichier uploadés SI true
        if ($clean === true) ... etc ...
    }

  14. #14
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut
    Voici le code de ma fonction destroy personnalisée. J'exploite bien le parametre boolen et j'ai bien besoin de l'id de la session à traiter:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    function sessionDestroy($id, $keepFiles=true) {
      global $sess_save_path;
      global $path_commande_fichier;
      //On cherche la session à supprimer
      $query	= "SELECT userid FROM $sess_save_path WHERE sid='$id';";
      $result	= mysql_query($query);
      if ($row = mysql_fetch_array($result)) {
        //On reccupere l'id de l'utilisateur loggué (s'il y en a un)
        $userId	= intval("0".$row["userid"]);
        if ($userId!=0 && !$keepFiles) {
          //Construction du chemin contenant d'éventuels fichiers uploadés
          $diskFilePath	= $path_commande_fichier.$userId."/tempPan/";
          $scan = glob(rtrim($diskFilePath,'/').'/*');
          foreach($scan as $fileName){
            if(is_file($fileName))
              @unlink($fileName);
          }
        }
        //On supprime la session de la base
        $query	= "DELETE FROM $sess_save_path WHERE sid='$id';";
        $result	= mysql_query($query);
      }
      return($result);
    }

  15. #15
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Ouais, mais un coup c'est ceci : sessionDestroy($cleanFiles=false)
    1 seul paramètre, et false par défaut

    Et maintenant, comme par hasard c'est 2 paramètres et true par défaut.

    Si tu commence par donner de mauvaises infos et qu'au bout de 15 post donner une tout autre version, ça ne le fait pas

    Si cela t'amuse de donner de fausses infos et au compte goutte, pour ma part ça ne m'amuse pas.
    Ne sachant ce qui m'attends dans les 15 autres post suivant, puis j'ai l'impression que tu ne tiens pas compte à ce que je raconte, donc à quoi bon ... j'abandonne, désolé.

    A mon sens, il faudrait en 1er revoir t'as façon de demander une aide.


    Je passe le relais à qui veut.

  16. #16
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2010
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2010
    Messages : 88
    Par défaut
    Puisqu'on en est à se faire des politesses, moi aussi je peux être de mauvaise humeur et dire que j'ai passé la matinée à te réexpliquer des choses que j'avais déjà écrite (comme le fait que la suppression des fichiers dans le garbage collector fonctionne depuis le début et le pb n'est pas là)

    Alors si je m'exprime mal, j'en suis désolé, c'est certainement pas volontairement !!
    Merci d'avoir essayé mais dommage que tu finisses par réagir comme ça

Discussions similaires

  1. Gestion des sessions avec applet
    Par Mister Nono dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 01/08/2006, 18h27
  2. [JSP] Gestion des sessions
    Par ze veritable farf dans le forum Servlets/JSP
    Réponses: 10
    Dernier message: 28/06/2006, 10h44
  3. [Struts][JSP]gestion des session en JSP
    Par zola dans le forum Struts 1
    Réponses: 6
    Dernier message: 27/04/2006, 16h23
  4. gestion des sessions
    Par jeff_! dans le forum Langage
    Réponses: 4
    Dernier message: 20/03/2006, 22h09
  5. [tomcat] gestion des sessions
    Par sebos63 dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 12/10/2004, 14h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo