Je souhaite prolonger le délai d'expiration 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.
Alors, est-il possible de le faire uniquement avec du code php?
Je souhaite prolonger le délai d'expiration 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.
Alors, est-il possible de le faire uniquement avec du code php?
Réponses:
Le délai d'expiration de session est une notion qui doit être implémentée 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 assouplir un peu 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.
Si vos sessions sont implémentées avec des cookies (ce qu'ils sont probablement), et si les clients ne sont pas malveillants, vous pouvez définir une limite supérieure sur 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, la configuration session.gc_maxlifetime
avec 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 conserver 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 la même période. Ces deux étapes sont nécessaires pour obtenir le résultat attendu.
Si vous ne dites pas aux clients d'oublier leur identifiant de session après 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 ne sera pas déterministe. Cela est dû au fait que les sessions dont la durée de vie a expiré côté serveur ne sont pas récupérées immédiatement mais uniquement chaque fois que la session GC démarre. .
GC est un processus potentiellement coûteux, donc généralement la probabilité est plutôt faible voire nulle (un site Web recevant un grand nombre de visites renoncera probablement complètement au GC probabiliste et le programmera pour qu'il se produise 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 session.gc_maxlifetime
, mais la limite supérieure sera imprévisible.
Si vous ne définissez session.gc_maxlifetime
pas la même période, le serveur peut ignorer les données de session inactives antérieures à cela; 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 juste de démarrer.
Vous pouvez rendre les choses complètement contrôlables en utilisant une logique personnalisée pour placer également une limite supérieure sur l'inactivité de session; avec la limite inférieure d'en haut, cela donne un réglage strict.
Pour ce faire, enregistrez la limite supérieure avec le reste des données de 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;
Jusqu'à présent, nous ne nous sommes pas du tout préoccupés des valeurs exactes de chaque identifiant de session, mais uniquement de l'exigence que les données existent aussi longtemps que nous en avons besoin. Sachez que dans le cas (peu probable) où les identifiants de session vous importent, il faut veiller à les régénérer session_regenerate_id
lorsque cela est nécessaire.
session_start()
également (sinon aucun effet) et seulement si vous appelez toujours ces deux avant session_start
(sinon cela gc_maxlifetime
pourrait affecter toutes les sessions actuellement ouvertes, alors que session_set_cookie_params
cela ne peut affecter qu'une nouvelle session qui commence par la demande actuelle).
Si vous utilisez la gestion de session par défaut de PHP, le seul moyen de modifier de manière fiable la durée de session sur toutes les plates-formes est de changer php.ini . En effet, sur certaines plates-formes, le ramasse-miettes est implémenté via un script qui s'exécute à chaque fois (un script cron ) qui lit directement depuis php.ini , et donc toute tentative de le modifier au moment de l'exécution, par exemple viaini_set()
, n'est pas fiable et très probable ne fonctionnera pas.
Par exemple, dans les systèmes Debian Linux, le ramasse-miettes interne de PHP est désactivé par session.gc_probability=0
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, chaque demi heure). Ce travail cron recherche les sessions antérieures à la session.gc_maxlifetime spécifiée dans la configuration et, le cas échéant, elles sont supprimées. En conséquence, dans ces systèmes ini_set('session.gc_maxlifetime', ...)
est ignoré. Cela explique également pourquoi dans cette question: les sessions PHP expirent trop rapidement , l'OP avait des problèmes dans un hôte mais les problèmes ont cessé lors du passage à un hôte différent.
Donc, étant donné que vous n'avez pas accès à php.ini , si vous voulez le faire de manière portable, utiliser la gestion de session par défaut n'est pas une option. Apparemment, prolonger la durée de vie des cookies était suffisant pour votre hôte, mais si vous voulez une solution qui fonctionne de manière fiable même si vous changez d'hôtes, vous devez utiliser une alternative différente.
Les méthodes alternatives disponibles incluent:
Définissez un gestionnaire de session (sauvegarde) différent en PHP pour enregistrer vos sessions dans un répertoire différent ou dans une base de données, comme spécifié dans PHP: Custom Session Handlers (manuel PHP) , de sorte que le travail cron ne l'atteigne pas, et seulement PHP un garbage collection interne a lieu. Cette option peut probablement utiliser ini_set()
pour définir session.gc_maxlifetime mais je préfère simplement ignorer le paramètre maxlifetime dans mon gc()
rappel et déterminer la durée de vie maximale par moi-même.
Oubliez complètement la gestion de session interne PHP et implémentez votre propre gestion de session. Cette méthode présente deux inconvénients principaux: vous aurez besoin de vos propres variables de session globales, vous perdez donc l'avantage du$_SESSION
superglobal, et elle a besoin de plus de code donc il y a plus d'opportunités pour les bogues et les 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 sécurisés cryptographiquement pour éviter la prévisibilité de l'identifiant de session (conduisant à un éventuel détournement de session), et ce n'est pas si facile à faire avec PHP de manière portable. Le principal avantage est qu'il fonctionnera de manière cohérente sur toutes les plates-formes et que vous avez un contrôle total sur le code. C'est l'approche adoptée par exemple par le logiciel du forum phpBB (au moins la version 1; je ne suis pas sûr des versions plus récentes).
Il y a un exemple de (1) dans le documentation poursession_set_save_handler()
. L'exemple est long mais je vais le reproduire ici, avec les modifications pertinentes nécessaires pour prolonger la durée de la session. Notez également l'inclusion de session_set_cookie_params()
pour augmenter la durée de vie des cookies.
<?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 n'entrerai pas dans les détails ici.
php.ini
vos options pratiques, elles sont sévèrement limitées.
/usr/lib/php5/maxlifetime
ne pas calculer une valeur inférieure à 24 minutes. Vous ne pouvez donc pas définir les délais d'expiration de votre session sur une valeur inférieure à cela.
Ajouter un commentaire pour toute personne utilisant Plesk ayant 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 fonctionnera pas car Plesk a son propre script de ramasse-miettes exécuté à partir de cron.
J'ai utilisé la solution publiée sur le lien ci-dessous pour déplacer le travail cron d'une heure à une autre pour éviter ce problème, alors 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
Mettez $_SESSION['login_time'] = time();
dans la page d'authentification précédente. Et l'extrait ci-dessous dans chaque autre page où vous souhaitez 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.
}
Modifier: cela ne fonctionne que si vous avez déjà utilisé les ajustements dans d'autres articles ou désactivé le nettoyage de la mémoire 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 peuvent l'ignorer. De plus, détruire directement la session avec session_destroy()
au lieu 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.
Juste un avis pour un hébergement de partage serveur d' ou ajouté sur les 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 public_html et pour ne pas avoir accès à la publicité de l'extérieur. Pour mon cpanel / serveur a bien fonctionné les autorisations de dossier 0700. Essayez ...
code php =
#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);
ini_set('session.cache_expire', 57600);
ini_set('session.name', 'MyDomainA');
avant session_start ();
ou
.htaccess =
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 le serveur cpanel / php7 partagé. Un grand merci à: NoiS
Non. Si vous n'avez pas accès au php.ini, vous ne pouvez pas garantir que les changements auront un effet.
Je doute que vous ayez besoin de prolonger la durée de vos sessions.
Il a un délai d'attente assez raisonnable pour le moment et il n'y a aucune raison de le prolonger.
SELECT id FROM gallery WHERE SortOrder > $currentsortorder LIMIT 1
Vous pouvez remplacer les valeurs dans php.ini à partir de votre code PHP en utilisant ini_set()
.
session.gc_maxlifetime
n'est pas le paramètre qui contrôle la durée de vie de la session. Il peut être matraqué au travail comme si vous définissez session.gc_divisor
à 1
, mais c'est tout simplement horrible.
gc_maxlifetime
définit l'intervalle après lequel les données de session sont éligibles pour le ramasse-miettes - si GC se produit après que ce laps de temps se soit écoulé, les données de session seront détruites (avec les paramètres par défaut, cela équivaut à l'expiration de la session). Mais GC est déclenché de manière probabiliste à chaque démarrage de session, il n'y a donc aucune garantie que la session expirera réellement - vous pouvez tracer une courbe de probabilité en fonction du temps, mais cela ne ressemblera pas à un mur de briques. Ce n'est que la pointe de l'iceberg; voir stackoverflow.com/questions/520237/…