Událost onLoggedOut[] mi nefunguje pokažde

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

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) {
	// ...
    }

}
studna
Člen | 181
+
0
-

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ší“.

smi
Člen | 75
+
0
-

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
+
0
-

Teoreticky ano:

  1. Po kliknutí na odhlásit
  2. Zavření prohlížeče
  3. Prošlé session

Jenže prakticky je to jinak.

$user->onLoggedOut[] = function($user){
	$y = Time();
	// $y uložíš do DB k uživateli
};

A teď máš 3 varianty:

  1. Kliknutím na odkaz: čas kliknutí bude přibližně rovný času $y
  2. Zavření okna prohlížeče: čas zavření okna prohlížeče neznáš, $y bude čas znovunačtení stránky
  3. 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
+
0
-

studna napsal(a):

Teoreticky ano:

  1. Po kliknutí na odhlásit
  2. Zavření prohlížeče
  3. Prošlé session

Jenže prakticky je to jinak.

$user->onLoggedOut[] = function($user){
	$y = Time();
	// $y uložíš do DB k uživateli
};

A teď máš 3 varianty:

  1. Kliknutím na odkaz: čas kliknutí bude přibližně rovný času $y
  2. Zavření okna prohlížeče: čas zavření okna prohlížeče neznáš, $y bude čas znovunačtení stránky
  3. 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
+
0
-
  • 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

strong
Člen | 2
+
0
-

Mne nefunguje automaticke odhlasenie po zatvoreni firefox-u.
Ked firefox znova otvorim som stale prihlaseny co je nepripustne.
Ako to mam vyriesit?
Je potrebne urobit nejaky ajax request?
Alebo staci si opakovane posielat nejaku premennu z login formulara?

JuniorJR
Člen | 181
+
0
-

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
+
0
-

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
+
0
-

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.

Google radí

Editoval JuniorJR (26. 11. 2011 12:14)