User se odhlašuje i když by neměl
- Ondřej Mirtes
- Člen | 1536
Aneb jak někdo pozná, že opět vyvíjím nějaký web – stoupne frekvence mého přispívání na fórum :o)
Dělám přihlašování uživatelů. Navěsil jsem si na onAuthenticated a onSignedOut události, které mi u daného usera nastavují online flag na 1/0 (abych mohl vypisovat uživatele, kteří jsou právě online apod.). Pochvaloval jsem si, že Nette dokáže ten callback zavolat i v případě, že nastane odhlášení kvůli zavření browseru. Geniální :)
Jenže to z nějakého neznámého důvodu přestalo fungovat – ta metoda se nezavolá (pokud se přihlásím, zavřu browser a otevřu ho, tak flag v databázi je stále na 1, ale já jsem odhlášený) a dokonce mě to odhlašuje i tehdy, kdyby nemělo. Zkouším totiž kromě mého typického nastavení třeba i něco takového:
$user->setExpiration('+ 2 days');
Což by podle dokumentace mělo znamenat, že maximální doba inaktivity před odhlášením je 2 dny, nehledě na zavření browseru. Jenže mě to po zavření/otevření odhlásí (koukal jsem na tu Nette cookie a má fakt platnost relace do zavření browseru) a navíc se nezavolá ta událost.
Nějaké tipy, kde bych měl hledat příčinu nesprávného chování, případně které zdrojáky bych sem měl postnout? Díky moc.
Editoval LastHunter (24. 6. 2009 10:56)
- Ondřej Mirtes
- Člen | 1536
R2D2 napsal(a):
a nemáš nastavenou menší expiraci session? (do zavření)
někde (v bootstrapu?) bys měl mít cosi jako
<?php $session = Environment::getSession(); $session->setExpiration($expiration); $session->start(); ?>
Díky, už funguje jak má :) Co kdyby třída User vyhazovala výjimku, pokud není splněná tato podmínka? Chová se pak totiž dost nestandardně…
- Vyki
- Člen | 388
Taky jsem se na něčem podobném nachytal, ale naštěstí jsem měl u sebe poznámky a zdrojáky z Davidovo přednášky, které mi to pomohly vyřešit. Ono to dává logiku, že žádná samostatná session proměnná nemůže mít dobu expirace nastavenou na delší dobu než je nastaveno obecně pro session (všechny session).
Editoval Vyki (26. 1. 2010 16:08)
- Ondřej Mirtes
- Člen | 1536
Jo, na to jsem už taky přišel. Navíc by to hlásilo jako online lidi třeba ty, kteří na webu vůbec nejsou, ale mají aktivní „stálé přihlášení“ třeba na 14 dní.
Jako možné řešení se nabízí zaznamenávat „last click“
u každého uživatele a vybírat pak jen ty řádky, kde
"last_click > time() - 1800"
(kliky za poslední
půlhodinu).
Editoval Ondřej Mirtes (28. 1. 2010 18:01)
- Ondřej Mirtes
- Člen | 1536
Stačí dát volání toho updatu přihlášeného uživatele třeba do startupu BasePresenteru.
dibi::query('UPDATE [users] set [last_click]=%i', time(), ' WHERE [id]=%i', $this->getUser()->getIdentity()->getId());
A počet aktuálně online (aktivních uživatelů za poslední půlhodinu):
$onlineCount = dibi::fetch('SELECT count(*) FROM [users] WHERE [last_click]>%i', time() - 1800);
Žádný cron nebo něco takového zde není potřeba. Je to jen základní princip, třeba někoho napadnou „zlepšováky“.
Editoval Ondřej Mirtes (28. 1. 2010 18:02)
- i.magine
- Člen | 81
Tak to jsem nemel… kazdopadne porad to nebezi:
public function formLoginSubmitted(AppForm $form)
{
try {
$session = Environment::getSession();
$session->setExpiration("+ 5 days");
$user = Environment::getUser();
$user->setAuthenticationHandler(new Users);
$user->setExpiration('+ 5 days', FALSE);
$user->authenticate($form['username']->getValue(), $form['password']->getValue());
$this->presenter->redirect('UserAdmin:default');
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
Když se podívám do cookies tak po opětovném zapnutí prohlížeče už je PHPSESSID pryč. A vždy se u něj nastavuje Doba platnosti na žádnou hodnotu.
Díky
Editoval i.magine (29. 1. 2010 12:06)
- Ondřej Mirtes
- Člen | 1536
Přenes to nastavení expirace session do bootstrapu, jak ti radí příspěvek nad tím.
- Honza Kuchař
- Člen | 1662
@R2D2: a nemáš nastavenou menší expiraci session?
Nebylo vy fajn, kdyby to vyhazovalo výjimku?
Editoval honzakuchar (29. 1. 2010 13:17)