8797 sujets

Développement web côté serveur, CMS

Bonjour,

Cela fait un moment que je me bats avec mes sessions sans trouver de solution. J'avais mis ce problème de côté pendant un temps, mais me voilà obliger à le résoudre.

Ma session fonctionne correctement en mode "manuel"

Sur ma page de login j'ai :

index.php

if ($_POST['login']=='vince' && $_POST['pwd']=='test')
{
 $Lifetime = 10;
 ini_set("session.gc_maxlifetime", $Lifetime);
 session_start();		
 $_SESSION['user'] = $_POST['login'];
 $_SESSION['ESTIDENTIFIE']=true;
 header('location:accueil.php');
}


j'ai une fonction de contrôle :

function isIdentified()
{
  $Lifetime = 10;
  ini_set("session.gc_maxlifetime", $Lifetime);
  session_start();
  return (isset($_SESSION['ESTIDENTIFIE']) && $_SESSION['ESTIDENTIFIE']);
}


Que j'appelle au début de mes pages :

if (isIdentified()==false)
 	echo header('location:index.php');


Le problème est que je peux m'authentifier aujourd'hui, aller sur mes pages et continuer demain sans que ma session se soit déconnecté automatiquement. Par exemple au bout de 15 minutes l'utilisateur doit être déconnecté si ce dernier n'a pas fait de nouveau "postback"

Merci de votre aide.
Lors de la connexion, tu devrais avoir un session_regenerate_id(). ça peut aider.

Au pire, tu peux horodater le début de ta session en enregistrant un timestamp. Puis vérifier son ancienneté.
Le gc_maxlifetime fonctionne en coordination avec gc_probability et gc_divisor.

À chaque début de session, PHP tire un nombre entre 1 et gc_divisor. Si ce nombre est inférieur à gc_probability, alors le ramasse miette passe et efface les sessions qui n'ont pas été accédées depuis plus de gc_maxlifetime sont supprimées.

Ce fonctionnement veut dire que si le ramasse miette ne passe pas, tu peux avoir une session qui reste valide 10 ans.

Dans ton cas, tu es probablement seul sur ton serveur de test, du coup quand tu reviens après une longue période d'inactivité mais que ton cookie est encore présent dans le navigateur, PHP fait son tirage aléatoire avec gc_divisor à 100. S'il tire 1 alors il efface ton ancienne session et tu te retrouves déconnecté. S'il tire autre chose il n'efface rien, tu réutilises ta session, et tu lui redonnes encore 10 minutes de durée de vie.

Bref, tu as 1% de chance que ta durée d'expiration soit respectée quand tu es tout seul. Plus il y a de monde plus tu as des chances qu'un tiers ait eu un mauvais tirage avant que toi tu repasses, et donc que ta session soit effacée.


Note : ton utilisation de gc_maxlifetime ne fait probablement pas ce que tu as en tête. Utilisé ainsi, si ton ramasse miette passe, ce n'est pas *ta* session qui est limitée à 10 minutes, mais *toutes* les sessions en cours (qu'elles soient utilisées pour le login ou pour autre chose).
Si tu entendais bien ce fonctionnement, tu devrais mettre cette ligne dans un fichier de configuration quelque part (genre un config.php inclut en haut de tous les fichiers) au lieu de l'ajouter à pas mal d'endroits.


Si tu veux être *certain* de ne jamais dépasser une certaine date, et peu d'utilisateurs, tu peux soit passer le gc_divisor à 1 (ça forcera le ramasse miette à passer), soit ajouter une date/heure dans ta session et la vérifier manuellement.
Merci pour vos réponses.

J'ai eu la surprise en publiant sur "prod" (sur le net) de ne pas pouvoir définir mon maxlifetime & co, le ini_set étant refusé en modification.

Je n'ai donc pour le moment laissé que le reste.
Il faut que je retrouve mes vieux code (Php3/4) que je faisais pour trouver et tester si ça fonctionne encore demain...

J'ai également eu une seconde surprise :
mon DOCUMENT_ROOT n'est pas la racine de mon site, j'ai donc des scripts qui ne fonctionne pas, et malgrés un phpinfo, je ne trouve pas d’équivalent (hébergement : lerelaisinternet (nordnet). C'est la première fois que je me retrouve dans le cas.

_SERVER["DOCUMENT_ROOT"] : /usr/local/httpd/htdocs