Událost onLoggedOut[] mi nefunguje pokažde
- smi
- Člen | 75
Ještě jednou téma onLoggedOut[].
Po nastaveni onLoggedOut[] na statickou funkci v modelu se mi udalost spusti
jen pro logout (položka v menu Odhlaseni).
Nespustí se při zavření prohlížeče ani při odhlášení z důvodu
neaktivity.
Login funguje OK.
Poraďtě prosím, kde dělám chybu. Verze Nette 2.0 Alpha 2, DIBI 1.5 rc – tedy vše podle poslední mody :o)
abstract class BasePresenter extends Nette\Application\Presenter
{
public function startup() {
// Nastaveni onLoggedOut
Nette\Environment::getUser()->onLoggedOut[] = array('Log', 'logoutRecord');
// StartUp rodice
parent::startup();
}
}
class UzivatelPresenter extends ProtectedPresenter {
// Logout
public function renderOdhlaseni() {
// Logout user
$this->getUser()->logout(TRUE);
$this->redirect('Homepage:Default');
}
}
class Prihlaseni extends AppForm {
public function __construct($owner, $name) {
// Rodic
parent::__construct($owner, $name);
// Renderer
// ...
// Submit
$this->addSubmit('Prihlasit', 'Vstup');
$this->onSubmit[] = callback($this, 'prihlasitSubmitted');
}
public function prihlasitSubmitted(Prihlaseni $form) {
try {
// Inicializace logovani
Nette\Environment::getUser()->onLoggedIn[] = array('Log', 'loginRecord');
// Uz nastaveno ve startup() !
// Nette\Environment::getUser()->onLoggedOut[] = array('Log', 'logoutRecord');
// Inicializace
$values = $form->getValues();
$presenter = $this->getPresenter();
$user = $presenter->getUser();
// Prihlaseni
$user->setExpiration('+ 20 minutes', TRUE, TRUE);
$user->login($values['SEKK_ID'], $values['Heslo']);
// Presmerovani
$presenter->redirect('Encyklopedie:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
}
class Log extends \Nette\Object {
// Vlastnosti
protected $table;
// Staticke funkce
static public function loginRecord() {
// Inicializace
// ...
}
static public function logoutRecord() {
// Inicializace
$table = Nette\Environment::getConfig('tabulky')->Log;
$identity = Nette\Environment::getUser()->getIdentity();
$nazev = (empty($identity->data['Nazev2'])) ? $identity->data['Nazev1'] :
$identity->data['Nazev1'] . ', ' . $identity->data['Nazev2'];
$cas = time();
$ip = $_SERVER["REMOTE_ADDR"];
// Argumenty prikazu
$args = array(
'SEKK_ID' => $identity->id,
'Pracoviste' => $nazev,
'Obec' => $identity->data['Obec'],
'UnixTime' => $cas,
'Datum' => date("Y.m.d", $cas),
'Cas' => date("G:i:s", $cas),
'IP' => $ip,
'Domena' => gethostbyaddr($ip),
'Akce' => 'Logout',
);
// Vlozeni zaznamu - tady se stejne chyba nema kam vypsat, tak na co try
dibi::insert($table, $args)->execute();
}
// Konstruktor
public function __construct() {
// Tabulka s logovacimi zaznamy
$this->table = Nette\Environment::getConfig('tabulky')->Log;
}
public function StatistikaPristupu(\Nette\ArrayHash $hledani, $limit=-1, $offset=0) {
// ...
}
}
- smi
- Člen | 75
studna napsal(a):
Na serveru musíš nějak zjistit, že uživatel zavřel okno prohlížeče ⇒ nějaký ajaxový požadavek.
K tomu důvodu neaktivity – uživatel se neodhlašuje, prostě „vyprší“.
V dokumentaci pro Nette\Web\User se ale píše:
…
Událost onLoggedOut je zpracována po odhlášení uživatele, ať už se odhlásil sám nebo z důvodu neaktivity či zavření prohlížeče.
…
- studna
- Člen | 181
Teoreticky ano:
Jenže prakticky je to jinak.
$user->onLoggedOut[] = function($user){
$y = Time();
// $y uložíš do DB k uživateli
};
A teď máš 3 varianty:
- Kliknutím na odkaz: čas kliknutí bude přibližně rovný času $y
- Zavření okna prohlížeče: čas zavření okna prohlížeče neznáš, $y bude čas znovunačtení stránky
- Prošlé session: čas vypršení si můžeš vytáhnout ze session, jinak $y bude čas znovunačtení stránky
Snad neplácám blbosti. :)
Editoval studna (27. 5. 2011 14:32)
- smi
- Člen | 75
studna napsal(a):
Teoreticky ano:
Jenže prakticky je to jinak.
$user->onLoggedOut[] = function($user){ $y = Time(); // $y uložíš do DB k uživateli };
A teď máš 3 varianty:
- Kliknutím na odkaz: čas kliknutí bude přibližně rovný času $y
- Zavření okna prohlížeče: čas zavření okna prohlížeče neznáš, $y bude čas znovunačtení stránky
- Prošlé session: čas vypršení si můžeš vytáhnout ze session, jinak $y bude čas znovunačtení stránky
Snad neplácám blbosti. :)
To ale znamená, že Nette události 2) a 3) nehlidá ? A musim si ohlídat jinak – třeba přes Ajax při zavření ?
- bojovyletoun
- Člen | 667
- neaktivita a ruční logout jsou jasné
- zavření okna – nette pozná při dalším otevření prohlížeče podle druhého cookie s expirací při zavření prohlížeče. Tohle mi nefunguje v žádném browseru. Pouze pokud ručně smažu cookie nette -browser
- expirace – pokud se nevymeže ssid, tak to jde poznat
- pokud smažeš všechny cookies- není jak zjistit, kdo se odhlásil, kdy a jak
Pozor : onLoggedOut musí být nastaveno ještě před manipulací s objektem user (možná by stálo za to nastavit handlery v továrničce…).
Viz:
// bootsrap.php
$u = $configurator->container->user;
$u->onLoggedOut[] = function ($user){ // must be very first
Debugger:log($user->id . time()); //... logovací funkce
throw new \Exception($u->logoutReason); // pro informaci
};
$u->setExpiration(23); //tato funkce volá getSessionNamespace,
//která v zároveň kontroluje a odhlašuje uživatele
// proto eventy musí být zaregistrovány dříve!
dump($u->loggedIn); // tahle funkce také!
PS: vzpomněl jsem si na tento
bug , stačí přidat ->getRoles()
do User.php:L343:C33
- JuniorJR
- Člen | 181
strong napsal(a):
Mne nefunguje automaticke odhlasenie po zatvoreni firefox-u.
Ked firefox znova otvorim som stale prihlaseny co je nepripustne.
Dovolím si reagovat. Teď jsem toto zkoušel na své aplikaci a automatické odhlášení po zavření, resp. znovuotevření prohlížeče mi funguje (ve Firefoxu se nesmí při zavření uložit současná relace).
- strong
- Člen | 2
Vdaka za odpoved, ale to neriesi moj problem secure logout. Nemozem prikazat
userovi aby neukladal relace vo firefoxu. Vie mi niekto poradit ako na to
s automatickym odhlasovanim v Nette v pridade, ze session este neexpirovala
po zatvoreni prehliadaca a opatovno otvoreni?
Pouzivam verziu NetteFramework-2.0alpha-PHP5.3 pod apache2 v OS Linux …
Je to pre mna najdolezitejsia secure vec.
- JuniorJR
- Člen | 181
Asi bych zkusil ještě JS odchycením události window.unload a zavěšením handleru, který by provedl request na odhlášení… Browser window close event
Ale stejně to nebude 100% a žádné jiné řešení mě nenapadá, jelikož zavření prohlížeče je otázka klienta.
Editoval JuniorJR (26. 11. 2011 12:14)