Non persistence des sessions

Petit nouveau ! | 6 Messages

25 mai 2010, 15:33

Bonjour,

Tout d'abord, merci d'avance si vous lisez tout le pavé qui suis, désolé mais j'ai essayé de faire au plus court.

J'ai deux site sous la même architecture mvc2, avec les mêmes classes et jusque quelques vues, du css et deux trois variables de config qui changent. J'ai un panneau d'administration en ajax, voici comment je m'y suis pris :
- Lors de l'appel d'une fonctionnalité ajax, j'utilise jquery pour appeler un fichier php très simple, relatif à la fonction demandée. J'effectue dedans quelques contrôles de sécurité. En voici un aperçu :
session_start();
include_once("../../../ctrl.php");
$ctrl = new Ctrl("");
if($ctrl->checkGrant("ajaxAdmin") && isset($_SERVER["HTTP_REFERER"]) && ($_SERVER["HTTP_REFERER"] == $ctrl->getUrlBase()."admin.html" || $_SERVER["HTTP_REFERER"] == $ctrl->getUrlBase()."admin.html#")) {
	if(isset($_POST['id'])) {
		echo json_encode(mysql_fetch_array($ctrl->getTabNews($_POST['id'])));
	}
} else
	die("Vous n'avez pas le droit d'accéder à cette page");
J'appelle donc mon contrôleur qui utilise la classe User pour faire les vérifications nécessaires (je vérifie que la valeur de la variable $_SESSION['statut'] correspond bien à celle d'une session admin).
Voici un extrait de la fonction checkGrant() du contrôleur pour l'aperçu :
if($page == null) {
	$page = $this->page;
	$isAjax = false;
} else
	$isAjax = true;
$this->setWork();
$this->user = User::getInstance();
if($this->work->isPageAdmin($page)) {
	if(!($this->user->isAdmin())) {
		if($isAjax) {
			return false;
		} else {
			$this->msgErr = $this->setError(13);
			$_SESSION['msg'] = $this->msgErr;
			$_SESSION['codeErr'] = 13;
			header("Location: erreur.html");
			exit;
		}
	} else {
		if($isAjax)
			return true;
	}
}
La fonction isAdmin() ne fait que vérifier la variable de session comme dit plus haut.

Tout cela marche pour le mieux en local, mais quand je met les deux sites sur leur serveur respectif, problème ! Un des deux sites fonctionne parfaitement comme en local, par contre pour l'autre dès que j'utilise une fonctionnalité ajax, déjà ça ne marche pas, ça me dit que je n'ai pas les droits, et en plus ça m'efface mes variables de session... C'est bien le test checkGrant() qui est en cause. J'ai testé de renvoyer true automatiquement s'il s'agit d'une requête ajax, les fonctions dynamiques marchent mais dès que je change de page, tout fout le camp : plus de variables de session...

J'ai pourtant mis exactement le même code que pour l'autre site... Je me suis donc penché sur la configuration du serveur, et après un petit ajustement les php.ini des deux serveurs sont strictement identiques.

EDIT : je rajoute la section sessions du php.ini (je ne met pas celle de l'autre site, c'est la même) :

Code : Tout sélectionner

Session Support enabled Registered save handlers files user Registered serializer handlers php php_binary Directive Local Value Master Value session.auto_start Off Off session.bug_compat_42 On On session.bug_compat_warn On On session.cache_expire 180 180 session.cache_limiter nocache nocache session.cookie_domain no value no value session.cookie_httponly Off Off session.cookie_lifetime 0 0 session.cookie_path / / session.cookie_secure Off Off session.entropy_file no value no value session.entropy_length 0 0 session.gc_divisor 100 100 session.gc_maxlifetime 1440 1440 session.gc_probability 1 1 session.hash_bits_per_character 4 4 session.hash_function 0 0 session.name PHPSESSID PHPSESSID session.referer_check no value no value session.save_handler files files session.save_path /tmp /tmp session.serialize_handler php php session.use_cookies On On session.use_only_cookies Off Off session.use_trans_sid 0 0
Désolé, j'ai essayé de vous mettre ça bien en forme mais lors du post ça fout tout en l'air...

Bref, j'en perd mon latin.

Des idées ?
Modifié en dernier par enemy le 25 mai 2010, 15:44, modifié 1 fois.

Eléphanteau du PHP | 40 Messages

25 mai 2010, 15:40

tu as essayé de retourner le session_id() dans code ajax pour le comparer à celui de la page appelante ?
Des icones, des RFC

Petit nouveau ! | 6 Messages

25 mai 2010, 15:47

Oui, il est bien identique.

ViPHP
ViPHP | 1136 Messages

25 mai 2010, 17:42

Les deux sites en prod utilisent le même nom de domaine ?

Petit nouveau ! | 6 Messages

26 mai 2010, 09:17

Non, ils ont deux nom de domaine différents. Au cas où, l'hébergeur utilisé est iweb.

Petit nouveau ! | 6 Messages

04 juin 2010, 10:42

J'ai de nouvelles informations sur le problème, j'espère que ça parlera à quelqu'un.

Le second site en prod rencontre exactement le même problème que l'autre à présent, pourtant je n'ai touché à rien, c'est vraiment venu du jour au lendemain. Voilà où j'en suis :
  • J'ai désactivé le contrôle d'authentification lors des requêtes ajax, ainsi elles fonctionnent
  • Lors de l'actualisation de la page d'admin, mes variables de sessions sont bien vides, et je me fait jeter
  • J'ai checké à mort le php.ini et l'ai comparé avec celui de mon localhost, le problème ne viendrait pas de là normalement
Mais là où ça devient intéressant, c'est qu'il n'y a aucun problème avec les fonctionnalités ajax qui n'utilisent pas la base de données... Mes variables de sessions restent bien pleine !

Pour mes accès base, j'utilise une classe perso avec une fonction query qui ouvre la connexion BDD avant la requête et la ferme juste après. En voici un extrait :
	public function query($request, $tab = null, $autoClose = true, [...]) {
		$this->link = null;
		if($this->link == null) {
			$rC = $this->connect($onTechno);
			if($rC != true) {
				return $rC;
			}
		}
		[...]
		$retourReq = mysql_query($request, $this->link);
		if($autoClose) {
			$retourClose = $this->close();
			if(is_numeric($retourClose))
				return $retourClose;
		}
		[...]
	}

	private function connect($onTechno = false) {
		[...]
			$srv = self::SRV;
			$log = self::LOGIN;
			$pass = self::PASS;
			$db = self::BASE;
		try {
			$this->link = mysql_connect($srv, $log, $pass);
			if($this->link == false)
				return 32;
			else {
				if(mysql_select_db($db, $this->link))
					return true;
				else
					return 33;
			}
		} catch(Exception $e) {
			return 31;
		}
	}

	public function close() {
		if($this->link != null) {
			if(mysql_close($this->link)) {
				$this->link = null;
				return true;
			}
			else
				return 37;
		} else
			return false;
	}
Bref, on dirai que l'exécution d'une requête sql m'efface ma session, alors que je n'y fait aucune référence. Bizarre non ?

EDIT : après de malheureux autres tests, il semble que me sois fourvoyé sur la voie du problème de base de données... Le problème est bien lors de l'appel d'un fichier php externe par ajax, bien qu'il y est le session_start() dedans... Pour info, j'ai essayé d'activer la directive session.auto_start dans le php.ini, ça ne fait pas de différence.

A rappeler ce qui se passe : quand j'arrive au fichier ajax, je n'ai déjà plus mes variables de session lors du session_start(). Pourtant, si je regarde le session_id() juste après, il n'a pas bougé. Au niveau des cookies, j'en ai 3 : un cookie connexion et un cookie PHPSESSID avec la même valeur, normal, mais j'ai aussi un deuxième cookie PHPSESSID avec une autre valeur ! Je ne sais pas si c'est le problème, mais bon, c'est étrange...

EDIT 2 : j'ai supprimé le troisième cookie, il ne se recrée plus, mais ça n'a pas pour autant réglé le problème... Le problème ne vient donc pas de lui.

Petit nouveau ! | 6 Messages

07 juin 2010, 10:00

Désolé de faire un triple post, mais j'ai vraiment besoin d'aide, le site doit être bouclé pour la fin de semaine.

J'ai tenté de nouvelles manip', et toujours le même problème :
  • Envoi des variables de sessions à la page ajax sous forme json : ok, mes variables de sessions sont bien remplies du côté de la page ajax, je peux donc faire mon checkGrant sans problème. Mais dès que j'actualise ma page admin.htm, mes variables de session sont encore une fois vides.
  • Rétablissement des variables de session une fois la requête ajax effectuée : je réutilise l'array chargé en début de page avec les variables de sessions pour être sûr qu'elles soient toujours renseignées. Encore que dalle.
  • J'envoie à ma page ajax le SSID en GET, puis en POST, puis en GET et en POST (là ça commence à être le début du craquage) :

    Code : Tout sélectionner

    $.post("v/js/ajax/getTableUser.php?PHPSESSID="+ssid, {id: id_user, svars: SESSION_VARS, SESSID: ssid},
    session_start();
    session_id($_POST["SESSID"]);
    Là encore, échec.
  • J'ai même tenté ça au début de ma page admin.htm :
    ini_set('session.gc_maxlifetime', 7200);
    Évidemment, ça ne m'avance pas non plus...
J'ai beau passer des heures sur google en français et en anglais, je ne trouve rien qui pourrait m'aider...

Je rappelle que le site fonctionne en local, et fonctionnait encore il y a peu online...

ViPHP
ViPHP | 4039 Messages

07 juin 2010, 10:12

Juste au cas ou, l'horloge interne des serveurs est bien correcte ?

Ca fait partie des petites choses qui peuvent saboter les sessions ^-^
Ceci dit, sur un hébergement mutualisé, il est très improbable qu'il soit désynchronisé.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Petit nouveau ! | 6 Messages

07 juin 2010, 10:22

On dirait bien que oui ! J'ai testé ceci :
echo date("r");
Ça me renvoie :

Code : Tout sélectionner

Mon, 07 Jun 2010 04:16:38 -0400
Décalage de 6h donc ! Je vais tester de passer session.gc_maxlifetime à une valeur supérieur à 6h, je verrai si c'est bien ça le problème.

EDIT : le changement du session.gc_maxlifetime n'a pas aidé, mais ça ne veut peut être rien dire, non ? (je l'ai passé à 8h)

EDIT 2 : je viens de me rendre compte que j'ai été con dans mon enthousiasme, c'est assez logique puisque le serveur est sûrement situé au canada...