chyba regenerace session při AJAXové komunikaci
- Keksa
- Člen | 23
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 | 8218
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
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 | 8218
Používá se v té aplikaci iframe? A projevuje se to ve více prohlížečích?
- David Grudl
- Nette Core | 8218
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
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 | 8218
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?
- David Grudl
- Nette Core | 8218
Nejsem to schopen nasimulovat a kde je problém netuším. Možná to ještě zkus na jiném hostingu.