174 votes

Comment modifier le délai d'expiration de la session en PHP ?

Je voudrais étendre le délai d'attente de la session en php.

Je sais qu'il est possible de le faire en modifiant le fichier php.ini. Mais je n'y ai pas accès.

Est-il possible de le faire uniquement avec du code php ?

2 votes

1 votes

Related, ceci est dans php.ini, mais je pense que vous pouvez utiliser ini_set comme @matino a dit stackoverflow.com/questions/520237/

357voto

Jon Points 194296

Le délai d'expiration de la session est une notion qui doit être mise en œuvre dans le code si vous voulez des garanties strictes ; c'est le seul moyen vous pouvez être absolument certain qu'aucune session ne survivra jamais après X minutes d'inactivité.

Si un léger relâchement de cette exigence est acceptable et que vous êtes d'accord pour placer une limite inférieure au lieu d'une limite stricte à la durée, vous pouvez le faire facilement et sans écrire de logique personnalisée.

La commodité dans les environnements détendus : comment et pourquoi ?

Si vos sessions sont mises en œuvre avec des cookies (ce qui est probablement le cas), et si les clients ne sont pas malveillants, vous pouvez fixer une limite supérieure à la durée de la session en modifiant certains paramètres. Si vous utilisez la gestion de session par défaut de PHP avec les cookies, le paramètre session.gc_maxlifetime ainsi que session_set_cookie_params devrait fonctionner pour vous comme ceci :

// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);

// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);

session_start(); // ready to go!

Cela fonctionne en configurant le serveur pour qu'il conserve les données de session pendant au moins une heure d'inactivité et en indiquant à vos clients qu'ils doivent "oublier" leur identifiant de session après cette même période. Ces deux étapes sont nécessaires pour obtenir le résultat escompté.

  • Si vous ne dites pas aux clients d'oublier leur identifiant de session au bout d'une heure (ou si les clients sont malveillants et choisissent d'ignorer vos instructions), ils continueront à utiliser le même identifiant de session et sa durée effective sera indéterminée. En effet, les sessions dont la durée de vie a expiré du côté du serveur ne sont pas immédiatement mises à la poubelle, mais seulement à chaque fois que le GC de la session entre en action .

    La GC étant un processus potentiellement coûteux, la probabilité est généralement assez faible, voire nulle (un site Web recevant un grand nombre de visites renoncera probablement à la GC probabiliste et la programmera en arrière-plan toutes les X minutes). Dans les deux cas (en supposant que les clients ne coopèrent pas), la limite inférieure de la durée de vie effective des sessions sera de session.gc_maxlifetime mais la limite supérieure sera imprévisible.

  • Si vous ne définissez pas session.gc_maxlifetime Dans ce cas, un client qui se souvient encore de son identifiant de session le présentera mais le serveur ne trouvera aucune donnée associée à cette session, se comportant effectivement comme si la session venait de commencer.

La sécurité dans les environnements critiques

Vous pouvez rendre les choses complètement contrôlables en utilisant une logique personnalisée pour placer également un limite supérieure sur l'inactivité de la session ; avec la limite inférieure ci-dessus, on obtient un paramètre strict.

Pour ce faire, sauvegardez la limite supérieure avec le reste des données de la session :

session_start(); // ready to go!

$now = time();
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
    // this session has worn out its welcome; kill it and start a brand new one
    session_unset();
    session_destroy();
    session_start();
}

// either new or old, it should live at most for another hour
$_SESSION['discard_after'] = $now + 3600;

Persistance de l'identifiant de session

Jusqu'à présent, nous ne nous sommes pas du tout préoccupés des valeurs exactes de chaque identifiant de session, mais seulement de l'exigence selon laquelle les données doivent exister aussi longtemps que nous en avons besoin. Sachez que dans le cas (improbable) où les identifiants de session sont importants pour vous, il faut veiller à les régénérer avec la fonction session_regenerate_id lorsque cela est nécessaire.

0 votes

Question : si je l'appelle, disons toutes les minutes, est-ce qu'il augmentera sa limite ? Par exemple, à 10:00, je l'appelle pour que sa limite soit de 11:00, après 1 minute, 10:01, la limite sera-t-elle de 11:01 ?

0 votes

@oneofakind : Si vous appelez quoi exactement ?

1 votes

Ceux-ci : ini_set('session.gc_maxlifetime', 3600) ; session_set_cookie_params(3600) ;

38voto

Pedro Gimeno Points 109

Si vous utilisez la gestion de session par défaut de PHP, la seule façon de modifier de manière fiable la durée de la session sur toutes les plates-formes est de changer la valeur de l'option php.ini . C'est parce que sur certaines plates-formes, le ramassage des déchets est mis en œuvre par le biais d'un script qui s'exécute à un moment donné (un cron script) qui lit directement à partir de php.ini et, par conséquent, toute tentative de le modifier au moment de l'exécution, par exemple par le biais de l'option ini_set() ne sont pas fiables et risquent fort de ne pas fonctionner.

Par exemple, sur les systèmes Debian Linux, le ramasse-miettes interne de PHP est désactivé par le paramétrage de session.gc_probability=0 par défaut dans la configuration, et se fait à la place via /etc/cron.d/php, qui s'exécute à XX:09 et XX:39 (c'est-à-dire toutes les demi-heures). Cette tâche cron recherche les sessions plus anciennes que la date de début de la session. session.gc_maxlifetime spécifiés dans la configuration, et s'ils sont trouvés, ils sont supprimés. Par conséquent, dans ces systèmes ini_set('session.gc_maxlifetime', ...) est ignorée. Cela explique aussi pourquoi dans cette question : Les sessions PHP se terminent trop rapidement L'OP a eu des problèmes avec un hôte mais les problèmes ont cessé en passant à un autre hôte.

Donc, étant donné que vous n'avez pas accès à php.ini Si vous voulez le faire de manière portative, l'utilisation de la gestion de session par défaut n'est pas une option. Apparemment, l'extension de la durée de vie des cookies était suffisante pour votre hôte, mais si vous voulez une solution qui fonctionne de manière fiable même si vous changez d'hôte, vous devez utiliser une autre solution.

Les méthodes alternatives disponibles comprennent :

  1. Définissez un gestionnaire de session (sauvegarde) différent en PHP pour sauvegarder vos sessions dans un autre répertoire ou dans une base de données, comme spécifié dans la rubrique PHP : Gestionnaires de session personnalisés (manuel PHP) de sorte que le cron ne l'atteint pas, et seul le garbage collector interne de PHP a lieu. Cette option permet probablement d'utiliser ini_set() pour fixer session.gc_maxlifetime mais je préfère ignorer le maxlifetime dans mon gc() et déterminer la durée de vie maximale par moi-même.

  2. Oubliez complètement la gestion interne des sessions de PHP et implémentez votre propre gestion des sessions. Cette méthode a deux inconvénients principaux : vous aurez besoin de vos propres variables globales de session, vous perdrez donc l'avantage de l'option $_SESSION superglobal, et il nécessite plus de code, donc plus de possibilités de bogues et de failles de sécurité. Plus important encore, l'identifiant de session doit être généré à partir de nombres aléatoires ou pseudo-aléatoires cryptographiquement sécurisés pour éviter la prévisibilité de l'identifiant de session (conduisant à un possible détournement de session), et ce n'est pas si facile à faire avec PHP de manière portable. L'avantage principal est que cela fonctionnera de manière cohérente sur toutes les plateformes et que vous avez un contrôle total sur le code. C'est l'approche adoptée, par exemple, par l'initiative phpBB le logiciel du forum (au moins la version 1 ; je ne suis pas sûr des versions plus récentes).

Il y a un exemple de (1) dans les la documentation pour session_set_save_handler() . L'exemple est long mais je le reproduis ici, avec les modifications nécessaires pour prolonger la durée de la session. Notez l'inclusion de session_set_cookie_params() pour augmenter la durée de vie des cookies également.

<?php
class FileSessionHandler
{

    private $savePath;
    private $lifetime;

    function open($savePath, $sessionName)
    {
        $this->savePath = 'my_savepath'; // Ignore savepath and use our own to keep it safe from automatic GC
        $this->lifetime = 3600; // 1 hour minimum session duration
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath, 0777);
        }

        return true;
    }

    function close()
    {
        return true;
    }

    function read($id)
    {
        return (string)@file_get_contents("$this->savePath/sess_$id");
    }

    function write($id, $data)
    {
        return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
    }

    function destroy($id)
    {
        $file = "$this->savePath/sess_$id";
        if (file_exists($file)) {
            unlink($file);
        }

        return true;
    }

    function gc($maxlifetime)
    {
        foreach (glob("$this->savePath/sess_*") as $file) {
            if (filemtime($file) + $this->lifetime < time() && file_exists($file)) { // Use our own lifetime
                unlink($file);
            }
        }

        return true;
    }
}

$handler = new FileSessionHandler();
session_set_save_handler(
    array($handler, 'open'),
    array($handler, 'close'),
    array($handler, 'read'),
    array($handler, 'write'),
    array($handler, 'destroy'),
    array($handler, 'gc')
    );

// the following prevents unexpected effects when using objects as save handlers
register_shutdown_function('session_write_close');

session_set_cookie_params(3600); // Set session cookie duration to 1 hour
session_start();
// proceed to set and retrieve values by key from $_SESSION

L'approche (2) est plus compliquée ; en gros, vous devez réimplémenter toutes les fonctions de session par vous-même. Je ne vais pas entrer dans les détails ici.

0 votes

Quelqu'un peut-il le confirmer ?

0 votes

@Oli : Cela semble correct après une lecture superficielle. Vous pourriez également vouloir regarder stackoverflow.com/questions/520237/ mais si vous n'avez pas accès à l'Internet, vous ne pouvez pas le faire. php.ini vos options pratiques sont sévèrement limitées.

0 votes

De plus, sur Ubuntu 14, on dirait que /usr/lib/php5/maxlifetime ne calculera pas une valeur inférieure à 24 minutes. Vous ne pouvez donc pas définir des délais de session inférieurs à cette valeur.

9voto

ChriStef Points 39

Juste un avis pour un hébergement partagé ou ajouté sur des domaines =

Pour que vos paramètres fonctionnent, vous devez avoir un répertoire de session de sauvegarde différent pour le domaine ajouté en utilisant php_value session.save_path folderA/sessionsA .

Créez donc un dossier sur votre serveur racine, pas dans le répertoire public_html et ne doit pas être accessible à la publicité depuis l'extérieur. Pour mon cpanel/serveur, les permissions des dossiers fonctionnent bien. 0700 . Essayez...

# Session timeout, 2628000 sec = 1 month, 604800 = 1 week, 57600 = 16 hours, 86400 = 1 day
ini_set('session.save_path', '/home/server/.folderA_sessionsA');
ini_set('session.gc_maxlifetime', 57600); 
ini_set('session.cookie_lifetime', 57600);
# session.cache_expire is in minutes unlike the other settings above         
ini_set('session.cache_expire', 960);
ini_set('session.name', 'MyDomainA');

avant session_start();

ou mettez ceci dans votre .htaccess fichier.

php_value session.save_path /home/server/.folderA_sessionsA
php_value session.gc_maxlifetime 57600
php_value session.cookie_lifetime 57600
php_value session.cache_expire 57600
php_value session.name MyDomainA

Après de nombreuses recherches et tests, cela a bien fonctionné pour un serveur partagé cpanel/php7. Merci beaucoup à : NoiS

0 votes

J'ai juste dû changer save_path comme vous l'avez dit, cela a fonctionné sur mon serveur d'hébergement partagé.

4voto

Neil Walden Points 31

J'ajoute un commentaire pour tous ceux qui utilisent Plesk et qui ont des problèmes avec l'un des éléments ci-dessus, car cela me rendait fou, la définition de session.gc_maxlifetime à partir de votre script PHP ne fonctionne pas car Plesk a son propre script de collecte des déchets exécuté à partir de cron.

J'ai utilisé la solution postée sur le lien ci-dessous en déplaçant la tâche cron de l'heure à la journée pour éviter ce problème, puis la réponse ci-dessus devrait fonctionner :

mv /etc/cron.hourly/plesk-php-cleanuper /etc/cron.daily/

https://websavers.ca/plesk-php-sessions-timing-earlier-expected

3voto

Mettez $_SESSION['login_time'] = time(); dans la page d'authentification précédente. Et l'extrait ci-dessous dans toutes les autres pages où vous voulez vérifier le délai d'expiration de la session.

if(time() - $_SESSION['login_time'] >= 1800){
    session_destroy(); // destroy session.
    header("Location: logout.php");
    die(); // See https://thedailywtf.com/articles/WellIntentioned-Destruction
    //redirect if the page is inactive for 30 minutes
}
else {        
   $_SESSION['login_time'] = time();
   // update 'login_time' to the last time a page containing this code was accessed.
}

Edit : Cela ne fonctionne que si vous avez déjà utilisé les ajustements décrits dans d'autres articles, ou si vous avez désactivé le Garbage Collection, et que vous souhaitez vérifier manuellement la durée de la session. N'oubliez pas d'ajouter die() après une redirection, car certains scripts/robots pourraient l'ignorer. De même, détruire directement la session avec session_destroy() plutôt que de compter sur une redirection pour cela pourrait être une meilleure option, encore une fois, dans le cas d'un client malveillant ou d'un robot.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X