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 :

Utilisation de session_regenerate_id


Sujet :

Langage PHP

  1. #1
    Membre confirmé Avatar de alejandro
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2004
    Messages : 167
    Par défaut Utilisation de session_regenerate_id
    Tout d'abord bonjour à tous, mon problème viens d'une classe de gestion de sessions. J'utilise session_set_save_handler pour paramétrer le comportement de mes sessions et utiliser les fonctionnalités classiques de sessions php.

    Pour tenter de prévenir les fixations de sessions, je change l'id de session à chaque appel d'une nouvelle page. Ma classe n'est pas totalement finie mais la partie principale me pose un problème.

    J'ai l'impression que lorsque je fais appel à session_regenerate_id(), mon appel en base de données est fait deux fois. En effet, le nouvel identifiant de session est inséré à la place de l'ancien et le nouveau est inconnu au bataillon.

    Y aurait-il des problèmes connus entre l'implémentation de session_set_save_handler et session_regenerate_id ?

    Plus précisément j'aimerais savoir ce que fais réellement session_regenerate_id ? Est-ce que ça me rappelle un read() ou un write() ?

    Pour vous simplifier, le problème vient de mon constructeur car la classe se comporte comme prévu si je comment la ligne session_regenerate_id();

    Voici mon code :
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    <?php
     
    /**
     * @package   Libraries
     * @lastmodif  2009.08.24:03.16PM
     * @version    1.0
     */
     
    if( ! class_exists( 'Lib_Session' ) )
    {
        /**
         * This class handle the whole session process. It will creates a new
         * session within db or get an existing one using the classic php session
         * functionnalities. Moreover, it attempts to prevent session fixation
         * by changing the session id twice at every page call.
         */
        class Lib_Session
        implements Vsf_Singleton_Interface
        {
            protected static $o_Instance; // Unique instance of the singleton
            protected static $o_Model;    // The database model instance
     
            const i_LastIdTimeOut = 30;   // The last session id validity
     
            // The current session data fields (corresponding to the db fields)
            protected static $s_SessionId, $s_LastSessionId, $i_SessionStart,
                             $i_LastActivity, $s_Userdata;
     
            /**
             * The protected constructor for the singleton instance
             */
            protected function __construct() 
            {
                session_set_save_handler(
                    array( & $this, 'open' ),
                    array( & $this, 'close' ),
                    array( & $this, 'read' ),
                    array( & $this, 'write' ),
                    array( & $this, 'destroy' ),
                    array( & $this, 'gc' )
                );
     
                // We set the values for some configuration options
                ini_set( 'session.name', 'sid' );
                ini_set( 'session.gc_probability', 10 );
                ini_set( 'session.gc_divisor', 100 );
                ini_set( 'session.gc_maxlifetime', 3600 );
     
                session_start();
                session_regenerate_id(); // Attempt to prevent session fixation
            }
     
            /**
             * Return and build if necessary the singleton instance of this class
             *
             * @return Lib_Session
             */
            public static function GetInstance()
            {
                // If there is no instance of the Lib_Session ...
                if( ! self::$o_Instance instanceof self )
                    self::$o_Instance = new self; // ... we create one.
                // We return the Lib_Session instance
                return self::$o_Instance;
            }
     
            /**
             * Open function, this works like a constructor and is executed when the
             * session is being opened. The open function expects two parameters, 
             * where the first is the save path and the second is the session name.
             *
             * @param  string $s_Path The session path
             * @param  string $s_Name The session name
             * @return bool (always true)
             */
            public static function Open( $s_Path, $s_Name )
            {
                self::$o_Model = new Model_Session;
                return true;
            }
     
            /**
             * Close function, this works like a destructor and is executed when the
             * session operation is done.
             *
             * @return bool (always true)
             */
            public static function Close()
            {
                @mysql_close();
                return true;
            }
     
            /**
             * Read function must return string value always to make save handler
             * work as expected. Return empty string if there is no data to read. 
             * Return values from other handlers are converted to boolean 
             * expression. TRUE for success, FALSE for failure.
             *
             * @param  string $s_SessionId The unique session id
             * @return string The userdata to store with the $_SESSION superglobal
             */
            public static function Read( $s_SessionId )
            {
                // Try to get the session data informations from database
                $h_Where = array( 'session_id' => $s_SessionId );
                $a_Model = self::$o_Model->Select( NULL, $h_Where, NULL, 0, 1 );
     
                // There is a corresponding session id into db
                if( count( $a_Model ) )
                {
                    // We get the content of $a_Model[0]
                    $h_Model = array_shift( $a_Model );
     
                    // The we set the session corresponding properties ...
                    self::$s_SessionId = $h_Model['session_id'];
                    self::$s_LastSessionId = $h_Model['last_session_id'];
                    self::$i_SessionStart = $h_Model['session_start'];
                    self::$i_LastActivity = $h_Model['last_activity'];
                    self::$s_Userdata = $h_Model['userdata'];
     
                    // ... and return the corresponding userdata
                    return self::$s_Userdata;
                }
                else // There is no corresponding session id into db
                {
                    // Check if there is an old session id into db
                    $h_Where = array( 'last_session_id' => $s_SessionId );
                    $a_Model = self::$o_Model->Select( NULL, $h_Where, NULL, 0, 1 );
     
                    // There is a corresponding old session id into db
                    if( count( $a_Model ) )
                    {
                        // We get the content of $a_Model[0]
                        $h_Model = array_shift( $a_Model );
     
                        // We must check whether the last session id is still valid
                        $i_LastValidTime = $h_Model['last_activity'] + self::i_LastIdTimeOut;
                        if( $i_LastValidTime > time() )
                        {
                            // The we set the session corresponding properties ...
                            self::$s_SessionId = $h_Model['session_id'];
                            self::$s_LastSessionId = $h_Model['last_session_id'];
                            self::$i_SessionStart = $h_Model['session_start'];
                            self::$i_LastActivity = $h_Model['last_activity'];
                            self::$s_Userdata = $h_Model['userdata'];
     
                            // ... and return the corresponding userdata
                            return self::$s_Userdata;
                        }
                    }           
                }
     
                return '';
            }
     
            /**
             * The "write" handler is not executed until after the output stream is 
             * closed. Thus, output from debugging statements in the "write" handler
             * will never be seen in the browser. If debugging output is necessary,
             * it is suggested that the debug output be written to a file instead. 
             *
             * @param  string $s_SessionId The unique session id
             * @param  string $h_SessionData The corresponding session data
             * @return bool Whether the write request succeeded or not
             */
            public function Write( $s_SessionId, $h_SessionData )
            {
                // Is a session model registered in database ?
                if( ! isset( self::$s_SessionId ) )
                {
                    // NO: We creates new session data
                    $h_Model = array( 'session_id' => $s_SessionId,
                                      'last_session_id' => self::$s_SessionId,
                                      'session_start' => time(),
                                      'last_activity' => time(),
                                      'userdata' => $h_SessionData );
     
                    return self::$o_Model->Insert( $h_Model );
                }
                else
                {
                    // YES: We creates a new session id ...
                    $h_Model = array( 'session_id' => $s_SessionId,
                                      'last_session_id' => self::$s_SessionId,
                                      'session_start' => self::$i_SessionStart,
                                      'last_activity' => time(),
                                      'userdata' => $h_SessionData );
     
                    // ... and update the session data !
                    $h_Where = array( 'session_id' => self::$s_SessionId );
                    return self::$o_Model->Update( $h_Model, $h_Where );
                }
     
            }
     
            /**
             * The destroy handler, this is executed when a session is destroyed
             * with session_destroy() and takes the session id as its only parameter 
             *
             * @param  string $s_SessionId The unique session id
             * @return bool Whether the delete request succeeded or not
             */
            public function Destroy( $s_SessionId )
            {
                // Check whether session is registered in db ?
                if( isset( self::$s_SessionId ) )
                {
                    // Where session_start < actual time - session maxlifetime
                    $h_Where = array( 'field' => 'session_id',
                                      'operator' => '=',
                                      'value' => $s_SessionId
                                    );
     
                    // Delete the expired sessions
                    self::$o_Model->Delete( array( 0 => $h_Where ) );
                }
     
                return true;
            }
     
            /**
             * The garbage collector, this is executed when the session garbage 
             * collector is executed and takes the max session lifetime as its 
             * only parameter. 
             *
             * @param  string $i_MaxLifeTime The maximum lifetime for a session
             * @return bool (always true)
             */
            public function Gc( $i_MaxLifeTime )
            {
                // Where session_start < actual time - session maxlifetime
                $h_Where = array( 'field' => 'session_start',
                                  'operator' => '<',
                                  'value' => time() - $i_MaxLifeTime
                                );
     
                // Delete the expired sessions
                self::$o_Model->Delete( array( 0 => $h_Where ) );
     
                return true;
            }
        }
    }

  2. #2
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    je sais pas si j'ai tout bien compris mais pour récupérer le nouveau session_id() il faut écrire quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    session_regenerate_id(); // Regénère l'ID
    $sess_id = session_id();  // Récupère le nouvel ID
    Si je suis à côté de la place, suis désolé

  3. #3
    Membre confirmé Avatar de alejandro
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2004
    Messages : 167
    Par défaut
    Merci pour ta réponse darkstar mais je viens d'identifier mon problème :

    En fait lorsque je fais un session_regenerate_id, il se passe que ma première session fait un appel via la méthode Write() à la base de données et met correctement à jour mes champs. L'ancien identifiant de session est bien mis dans Last_Session_Id et le nouveau est bien mis dans Session_Id.

    Le problème c'est que ma nouvelle session créée avec Session_Regenerate_Id en fait de même ... autrement dit j'ai mon nouvel identifiant de session qui passe lui même en ancien et un nouvel identifiant de session qui vient se loger dans le champ session_id.

    Est-il possible d'éviter ce comportement ?

  4. #4
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    hmm d'après ce que je comprends, il te faut rajouter une simple condition afin d'empêcher le double UPDATE.
    Une condition qui dit : "houlala mon grand, t'essaye de mettre la session courrante en last_session ! ça c'est pas bien ! arrête toi TISSOUITE !!"
    (désolé fin de journée ^^)

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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