Session zůstává aktivní i po zavření prohlížeče i když by neměla

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

Ahoj experti,
řeším problém s expirací session (resp. $user). Naproti mnoha příspěvkům, že se session ukončí po zavření probhlížeče i když nemají, já řeším opačný problém, session mi po zavření prohlížeče nevyexpiruje i když by měla.

V configu mám:

	nette:
		session:
			save_path: "%tempDir%/sessions"
			autoStart: smart
			expiration: + 1 year

Po přihlášení pak podle zaškrtnutí políčka pamatovat volám buď:

$this->user->setExpiration("+ 1 year", FALSE);

nebo:

$this->user->setExpiration("+ 1 year", TRUE);

Ale v obou případech po zavření prohlížeče a opětovném otevření zůstává přihlášení aktivní.
Pro session se založí soubor v umístění podle configu, ale po zavření prohlížeče se nesmaže.
Napadá někoho čím by to mohlo být? Nebo co zkontrolovat?

Předem díky

newPOPE
Člen | 648
+
0
-

Nieco podobne som riesil uz davnejsie s FF. Zalezalo tam vtedy na nastaveni toho co FF otvori po restarte. Ked som tam mal naposledy otvorene karty tak ako keby sa vsetko freezlo a nevyexpyrovalo to. Korektne to fungovalo tusim len pri defaultnych nastaveniach.

Treba skusat :-)

Merllinn
Člen | 28
+
0
-

Zajímavá myšlenka, ale myslím, že tohle nebude ono…přihlášení si pamatuje i Chrome, Opera i IE u kterých se stav při uložení neuchovává.
Navíc tohle bych rozumněl, že může nastat, pokud se session ukládá do cookies, ale když se ukládají do souboru, tak jeho smazání/ponechání by na ukládání panelů prohlížečem reagovat nemělo.

Asi zkusím nějaký úplně simple project, jak se to bude chovat tam, abych vyloučil, že je zavleklá chyba někde v aplikaci :-/

Merllinn
Člen | 28
+
0
-

Tak jsem udělal rychlý test na čistém sandboxu a výsledek je překvapivý:
v configu je expiration: ‚+ 14 days‘
Mám pouze jednu session proměnnou a šablonu do které ji vypisuju, handler, který ji nastavuje a nastavení expirace:

$this->ses->setExpiration("+14 days", true);

Když ji jednou odkazem na handler nastavím, už zůstane nastavená i po zavření/otevření všech prohlížečů, zkoušel jsem i restart FF, ale proměnná je pořád nastavená.

Je možnost nějak zjistit aktuální nastavení expirace session? Nastavení je jasny, ale jde to zpětně i zjistit?

EDIT: problém nevyřešilo ani nastavení FF, aby startoval do čisté stránky a nepamatoval si otevřené panely.

Editoval Merllinn (23. 9. 2012 0:57)

Merllinn
Člen | 28
+
0
-

Tak jsem zjistil, že:

  • session (přihlášení) vyprší po čase definovaném v configu (+1 week)
  • $this->user->setExpiration(„+ 1 minute“); je úplně bez efektu, sesion vyprší až po čase definovaném v configu (týden)
  • aplikace kódem nastavení $this->user->setExpiration() projde, to jsem ověřil, takže setExpiration proběhne, ale na vypršení cookies to nemá efekt
  • nastavení FF jestli si pamatovat otevřené panely nehraje roli, tohle chování je stejné na obojím

Je to chyba v Nette, nebo mi stále něco uniká?

Editoval Merllinn (23. 9. 2012 18:44)

Ivorius
Nette Blogger | 119
+
0
-

Dostal si na to někde odpověď?

Merllinn
Člen | 28
+
0
-

Bohužel ne a stále jsem to nevyřešil. Nevím jestli si s tím nikdo neví rady, nebo se jen nechce podělit, ale stále to nefunguje. Session si v sobě nese informaci, že se má po zavření prohlížeče zavřít (kontrolováno z debug panelu), ale po zavření prohlížeče je přihlášení stále aktivní :-(
Respektive, to že si session držela nastavení z configu byla moje chyba…teď se do ní propíše nastavení setExpiration, ale i tak po zavření prohlížeče nevyprší

Editoval Merllinn (7. 9. 2013 20:04)

Majkl578
Moderator | 1364
+
0
-

Nette rozlišuje zavření prohlížeče podle hodnoty/existence cookie nette-browser. Můžeš prozkoumat, jestli při zavření zmizí (tj. po dalším spuštění by prvně neměla existovat a později mít jinou hodnotu než dříve).

Merllinn
Člen | 28
+
0
-

Stav je takový:

  • po otevření stránky aplikace se hodnota cookie nette-browser nastavila
  • po zavření a znovu otevření prohlížeče cookie není
  • po otevření stránky aplikace se nastaví na novou hodnotu
  • uživatel, který byl přihlášen před zavřením (s nastavením $this->user->setExpiration(0, true, true);) je stále přihlášen

Díky za zájem Majkle, kdyby se našla příčina, tak bych byl moc rád.

s4muel
Člen | 92
+
0
-

@Merllinn: skus si prejst aj toto: https://forum.nette.org/…i-prohlizece (zatial vsak bez riesenia)

edit: aha, teraz vidim, ze sa ti cookie po zavreti prehliadaca vymaze… tak to je trochu ine. pozeral si dobre?

Editoval s4muel (9. 9. 2013 8:10)

enumag
Člen | 2118
+
0
-

Můžeš zkusit debugovat tenhle kus kódu. Měl by detekovat zavření browseru a vyexpirovat vše co zavřením expirovat má.

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

Můžeš zkusit debugovat tenhle kus kódu. Měl by detekovat zavření browseru a vyexpirovat vše co zavřením expirovat má.

Hmmm…detekce uzavření prohlížeče je bez problému, řádek 137 správně nastaví $browserClosed=true po otevření browseru (pak už false).
Ale problém je o kus dál na řádku 144, protože proměnná $nf nemá prvek „META“, pouze „DATA“.

Editoval Merllinn (9. 9. 2013 11:00)

enumag
Člen | 2118
+
0
-

@Merllinn: Ok, jako další krok bych viděl dumpování $_SESSIONtéhle fci, konkrétně jestli obsahuje META. Pokud ne tak asi nezbývá než debugovat třídu SessionSection.

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

@Merllinn: Ok, jako další krok bych viděl dumpování $_SESSIONtéhle fci, konkrétně jestli obsahuje META. Pokud ne tak asi nezbývá než debugovat třídu SessionSection.

Tak tam je to OK, $_SESSION ve funkci setExpiration META obsahuje.

enumag
Člen | 2118
+
0
-

@Merllinn: A obsahuje to co má? Možná to později smaže metoda clean.

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

@Merllinn: A obsahuje to co má? Možná to později smaže metoda clean.

Nejsem si jistý co přesně by měla obsahovat, ale předpokládám, že nějaký obraz toho co je v DATA, ale to neobsahuje.
V DATA je 14 prvků (11 z nich je prázdných – NULL) a poslední je ‚Nette.Forms.Form/CSRF‘, ale META obsahuje pouze jeden prvek a to ‚Nette.Forms.Form/CSRF‘

Editoval Merllinn (9. 9. 2013 11:38)

enumag
Člen | 2118
+
0
-

Nejsem si jistý co přesně by měla obsahovat

Můžeš sem hodit co obsahuje META a DATA? Respektive co obsahují na začátku té fce setExpiration a co na konci?

O CSRF nejde, mělo by tam být něco ohledně identity uživatele (imho), klíč ‚Nette.Http.UserStorage/‘.

Editoval enumag (9. 9. 2013 11:42)

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

Nejsem si jistý co přesně by měla obsahovat

Můžeš sem hodit co obsahuje META a DATA? Respektive co obsahují na začátku té fce setExpiration a co na konci?

O CSRF nejde, mělo by tam být něco ohledně identity uživatele (imho), klíč ‚Nette.Http.UserStorage/‘.

Nene, ten tam není ani na začátku funkce, jen CSRF. Jediný rozdíl v těch dvou verzích je (nečekaně) v nastavení expirace.
Tady jsou dumpy $_SESSION[„__NF“]:
na začátku funkce

<?php
array(5) {
  'C' =>
  int(49)
  'Time' =>
  int(1378716471)
  'B' =>
  string(10) "r5e76mlggj"
  'DATA' =>
  array(14) {
    'Nette.Http.UserStorage/' =>
    array(2) {
      'authenticated' =>
      bool(false)
      'identity' =>
      class Nette\Security\Identity#137 (4) {
        ...
      }
    }
    'lang' =>
    array(1) {
      'lang' =>
      string(2) "en"
    }
    'journal-owned' =>
    NULL
    'journal-secured' =>
    NULL
    'journal' =>
    NULL
    'register' =>
    NULL
    'photo' =>
    NULL
    'fullPhoto' =>
    NULL
    'registerSpyForm' =>
    NULL
    'registerObjectForm' =>
    NULL
    'registerPhotoForm' =>
    NULL
    'registerLocatorForm' =>
    NULL
    'statements' =>
    NULL
    'Nette.Forms.Form/CSRF' =>
    array(1) {
      'key' =>
      string(10) "kthcncwseo"
    }
  }
  'META' =>
  array(1) {
    'Nette.Forms.Form/CSRF' =>
    array(1) {
      'key' =>
      array(2) {
        ...
      }
    }
  }
}
?>

a na konci

<?php
array(5) {
  'C' =>
  int(49)
  'Time' =>
  int(1378716471)
  'B' =>
  string(10) "r5e76mlggj"
  'DATA' =>
  array(14) {
    'Nette.Http.UserStorage/' =>
    array(5) {
      'authenticated' =>
      bool(false)
      'identity' =>
      class Nette\Security\Identity#137 (4) {
        ...
      }
      'expireIdentity' =>
      bool(true)
      'expireBrowser' =>
      bool(true)
      'browserCheck' =>
      bool(true)
    }
    'lang' =>
    array(1) {
      'lang' =>
      string(2) "en"
    }
    'journal-owned' =>
    NULL
    'journal-secured' =>
    NULL
    'journal' =>
    NULL
    'register' =>
    NULL
    'photo' =>
    NULL
    'fullPhoto' =>
    NULL
    'registerSpyForm' =>
    NULL
    'registerObjectForm' =>
    NULL
    'registerPhotoForm' =>
    NULL
    'registerLocatorForm' =>
    NULL
    'statements' =>
    NULL
    'Nette.Forms.Form/CSRF' =>
    array(1) {
      'key' =>
      string(10) "kthcncwseo"
    }
  }
  'META' =>
  array(1) {
    'Nette.Forms.Form/CSRF' =>
    array(1) {
      'key' =>
      array(2) {
        ...
      }
    }
  }
}
?>
Merllinn
Člen | 28
+
0
-

enumag napsal(a):

@Merllinn: A obsahuje to co má? Možná to později smaže metoda clean.

Aha, tak už to mám. Je to opravdu o metodě clean().
Snažím se po sobě session uklízet a protože odebrání section ji pouze nastaví na null, chtěl jsem, aby se odstraňovaly úplně a tak jsem volal metodu clean nad celou session().
Pak jsem na to úplně zapomněl a ono to způsobuje tenhle problém, že session neexpiruje.
Po zakomentování $this->session->clean(); už přihlášení expiruje jak má.

Merllinn
Člen | 28
+
0
-

@enumag: opravdu hodně děkuju, tohle bych nikdy sám nenašel.
A existuje způsob jak odebrat prázdné sekce ze session? $section->remove() je pouze nastaví na null, ale v session je nechá.

enumag
Člen | 2118
+
0
-

Ta clean metoda by to imho způsobit neměla. Můžeš to tam vrátit a zkusit to ještě? Dost možná je tam bug. Při tomhle volání by se tady mělo do do META přidat něco jako 'browserClosed' => array('T' => 0, 'B' => TRUE).

EDIT: Nebo jinak, co obsahuje META předtím než spouštíš tu metodu clean a co obsahuje poté?

Editoval enumag (9. 9. 2013 12:08)

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

Ta clean metoda by to imho způsobit neměla. Můžeš to tam vrátit a zkusit to ještě? Dost možná je tam bug. Při tomhle volání by se tady mělo do do META přidat něco jako 'browserClosed' => array('T' => 0, 'B' => TRUE).

EDIT: Nebo jinak, co obsahuje META předtím než spouštíš tu metodu clean a co obsahuje poté?

Pkud zakomentuju $this->session->clean();, tak v META vidím odraz toho co je v DATA a pak se do toho přidá browserCheck' ⇒ array(2) {‚T‘ ⇒ NULL, ‚B‘ ⇒ bool(true) }, ale pokud provádím ten clean, tak se to do META nemělo kam propsat. Teď i když clean pustím, tak už v META data mám, takže to funguj i tak.

enumag
Člen | 2118
+
0
-

@Merllinn: Nechápu. Co jsi tedy změnil že už i ten clean funguje správně?

Merllinn
Člen | 28
+
0
-

@enumag: mě neexpiruje celá session, ale jenom userStorage. Po tom co jsem web pustil se zakomentovaným clean() se do session doplnili elementy do META (ty se ale udrží i po zavření prohlížeče).Takže i když to teď pustim s clean(), tak se to chová správně.

Pokud session natvrdo smažu, tak start aplikace se zakomentovaným clean() správně nastaví META, pokud clean ve startupu proběhle, pak se userStorage do META mezaloží

Editoval Merllinn (9. 9. 2013 12:27)

enumag
Člen | 2118
+
0
-

@Merllinn: To mi neni jasný, ta metoda clean by neměla smazat nic podstatného… Můžeš mi sem dát dumpy celého toho pole META před a po volání clean když předtím smažeš session? (Tedy ten případ co nefunguje dle očekávání.)

Editoval enumag (9. 9. 2013 12:43)

Merllinn
Člen | 28
+
0
-

@enumag: Ta metoda clean() kompletně celý META odebere. Tady jsou dumpy $_SESSION[‚__NF‘]:
před

<?php
array(5) {
  'C' =>
  int(1)
  'Time' =>
  int(1378723684)
  'B' =>
  string(10) "s5hv9ye8jw"
  'DATA' =>
  array(13) {
    'Nette.Http.UserStorage/' =>
    array(1) {
      'authenticated' =>
      NULL
    }
    'lang' =>
    array(1) {
      'lang' =>
      string(2) "en"
    }
    'journal-owned' =>
    NULL
    'journal-secured' =>
    NULL
    'journal' =>
    NULL
    'register' =>
    NULL
    'photo' =>
    NULL
    'fullPhoto' =>
    NULL
    'registerSpyForm' =>
    NULL
    'registerObjectForm' =>
    NULL
    'registerPhotoForm' =>
    NULL
    'registerLocatorForm' =>
    NULL
    'statements' =>
    NULL
  }
  'META' =>
  array(13) {
    'Nette.Http.UserStorage/' =>
    NULL
    'lang' =>
    NULL
    'journal-owned' =>
    NULL
    'journal-secured' =>
    NULL
    'journal' =>
    NULL
    'register' =>
    NULL
    'photo' =>
    NULL
    'fullPhoto' =>
    NULL
    'registerSpyForm' =>
    NULL
    'registerObjectForm' =>
    NULL
    'registerPhotoForm' =>
    NULL
    'registerLocatorForm' =>
    NULL
    'statements' =>
    NULL
  }
}
?>

a po

<?php
array(4) {
  'C' =>
  int(1)
  'Time' =>
  int(1378723684)
  'B' =>
  string(10) "s5hv9ye8jw"
  'DATA' =>
  array(13) {
    'Nette.Http.UserStorage/' =>
    array(1) {
      'authenticated' =>
      NULL
    }
    'lang' =>
    array(1) {
      'lang' =>
      string(2) "en"
    }
    'journal-owned' =>
    NULL
    'journal-secured' =>
    NULL
    'journal' =>
    NULL
    'register' =>
    NULL
    'photo' =>
    NULL
    'fullPhoto' =>
    NULL
    'registerSpyForm' =>
    NULL
    'registerObjectForm' =>
    NULL
    'registerPhotoForm' =>
    NULL
    'registerLocatorForm' =>
    NULL
    'statements' =>
    NULL
  }
}
?>
enumag
Člen | 2118
+
0
-

Aha takže ten clean prostě jen voláš v nesprávnou dobu a pak už nejsou platné původní reference do pole $_SESSION.

Ono to čištění provádí automaticky metoda close, jenže mám podezření že ta metoda close se nevolá nikdy.

Editoval enumag (9. 9. 2013 13:02)

Merllinn
Člen | 28
+
0
-

Podle mě tím, že se clean() zavolá už ve startupu, tak předběhne metodu přihlášení, ve které se teprve nastavuje expirace userStorage. A tím pádem je META prázdné, když ještě nemá nastaveou expiraci a clean() ji odebere.

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

Aha takže ten clean prostě jen voláš v nesprávnou dobu a pak už nejsou platné původní reference do pole $_SESSION.

Ono to čištění provádí automaticky metoda close, jenže mám podezření že ta metoda close se nevolá nikdy.

Jak říkáš ;-)
Každopádně díky za trpělivost, hodně jsi mi pomohl.

enumag
Člen | 2118
+
0
-

Aha tak to clean by se mělo volat automaticky vždycky.

Editoval enumag (9. 9. 2013 13:03)

Merllinn
Člen | 28
+
0
-

enumag napsal(a):

Aha tak to clean by se mělo volat automaticky vždycky.

Já jsem měl pocit, že jsem tu registraci někde zahlédl. Díky za tu poznámku, ušetřil jsi mi duplikované volání v shutdownu.

enumag
Člen | 2118
+
0
-

Mám pocit že by ta metoda clean měla být označena jako @internal a tedy by neměla být součástí API.