chyba regenerace session při AJAXové komunikaci

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Keksa
Člen | 23
+
0
-

Nette 2.1-dev (23. 3. 2012), PHP 5.3.10

Mám chatovou aplikaci která každých x sekund kontroluje změny pomocí AJAXu a vždy když proběhla regenerace session tak se „odhlásil“ uživatel (všechna jeho data v aktuální session byla smazána, tím pádem funkce $this->getUser()->isLoggedIn() v presenteru začala vracet false).

Opravil sem to tak, že na řádku 165 v Nette/Http/Session.php jsem $this->regenerateId(); změnil na:

if(!$this->request->isAjax()){
	$this->regenerateId();
}

Nezdá se mi to ale jako korektní řešení, tenhle problém by vlastně vůbec neměl nastat, tím pádem to zákaz při AJAXové komunikaci vlastně jenom obchází.
Nevím jestli jde o chybu v Nette, nebo v PHP. Co myslíte?

David Grudl
Nette Core | 8082
+
0
-

Jde o chybu v PHP. Zkus úplně poslední verzi Nette-dev, měla by obsahovat workaround. Dej prosím vědět, jestli pomohlo.

Keksa
Člen | 23
+
0
-

Bohužel, nepomohlo, chová se to furt stejně. Možná by to mohlo souviset s funkcí session_write_close, první komentář v dokumentaci k této funkci je:

Beware of session_write_close when calling PHP scripts from an Ajax page: this does not „finalize“ the session data writing, but in fact it resets it!

A btw nejnovější vývojová verze hlásí chybu v Nette/Config/Configurator.php (řádek 200) – Class ‚SystemContainer‘ not found.

EDIT: Tak se to chová tak nějak zvláštně, občas se to odhlásí, občas ne a občas to po refreshi stránky zase naskočí. (Aplikace informuje uživatele o odhlášení, pokud je při AJAXovém isLoggedIn false. Po zavření informačního okna se obnoví stránka.)

Editoval Keksa (23. 3. 2012 11:08)

David Grudl
Nette Core | 8082
+
0
-

Používá se v té aplikaci iframe? A projevuje se to ve více prohlížečích?

Keksa
Člen | 23
+
0
-

David Grudl napsal(a):

Používá se v té aplikaci iframe? A projevuje se to ve více prohlížečích?

Iframe nepoužívám nikde, projevuje se to ve všech prohlížečích (test ve FF 11.0, Opera 11.61 a Chrome 17.0.963.83).

David Grudl
Nette Core | 8082
+
0
-

Pokud si dám třeba do Dashboard/default.latte ajaxové volání v 10 sekundovém intervalu:

	<script src="jquery.js"></script>
	<script>
	setInterval(function(){
		$.get({link default}, function(payload) {
			console.log(payload);
		});
	}, 10000); // 10 sec
	</script>

Tak se mi nic neodhlásí, ani při regeneraci session id.

Nemáš tak třeba příliš krátkou expiraci?

Keksa
Člen | 23
+
0
-

Pro testování sem přenastavil v souboru Nette/Http/Session.php na hodnotu REGENERATE_INTERVAL na 60 sekund. Session, kterou používá aplikace má nastavenou hodnotu expirace na „+ 12 hours“. Aplikace každé 3 sekundy kontroluje, jestli existují nové příspěvky. Na začátku presenteru probíhá kontrola, jestli je uživatel přihlášen:

public function startup()
{
	parent::startup();
	if(!$this->getUser()->isLoggedIn()){
		if(!$this->isAjax()){
			$this->flashMessage('Nejste přihlášen(a).', 'error');
			$this->redirect('Homepage:');
		}else{
			$this->sendResponse(new Nette\Application\Responses\TextResponse('logout'));
		}
	}
}

V javascriptu je potom na začátku inicializován timer (doplněk do jquery, používá to klasicky setInterval):

chatTimer = $.timer(3000, function () {
	Chat.getPosts(0,true);
});

Chat.getPosts pomocí $.post tahá nové příspěvky (pokud existují) a pokud je payload === „logout“, tak po informování uživatele obnoví stránku a uživatel je přesměrován na homepage pomocí kontroly v presenteru.

EDIT: Jinak se to chová stejně jak na localhostu, tak na produkčním serveru (WEDOS hosting).
EDIT 2: Teď sem si všimnul, že je občas po obnovení stránky uživatel stále přihlášen, ale nemůžu v tom najít žádnou logiku.

Editoval Keksa (27. 3. 2012 19:38)

David Grudl
Nette Core | 8082
+
0
-

To znamená, že po 60 sekundách to oznámí payloadem, že uživatel je odhlášen, ale po redirectu je občas stále přihlášen?

Keksa
Člen | 23
+
0
-

David Grudl napsal(a):

To znamená, že po 60 sekundách to oznámí payloadem, že uživatel je odhlášen, ale po redirectu je občas stále přihlášen?

Přesně tak.

David Grudl
Nette Core | 8082
+
0
-

Nejsem to schopen nasimulovat a kde je problém netuším. Možná to ještě zkus na jiném hostingu.

Keksa
Člen | 23
+
0
-

David Grudl napsal(a):

Nejsem to schopen nasimulovat a kde je problém netuším. Možná to ještě zkus na jiném hostingu.

Škoda. Mno, opravim si to provizorně tak, že to zakážu pro ajax, bezbečnostní riziko je v tom imho téměř nulové. I tak díky. :)

David Grudl
Nette Core | 8082
+
0
-

Volání regenerateId() bylo v Nette zrušeno ve verzi 2.0.7