Chyba v Session – Automatické odhlašování a automatické prodlužování expirace session u FlashMessages

Bulldog
Člen | 110
+
0
-

Ahoj,
dokumentaci o přihlašování se píše cituji:

Ještě lze nastavit časový interval, po jehož uplynutí dojde k odhlášení uživatele (jinak se odhlásí s expirací session). K tomu slouží metoda setExpiration(), která se volá před login().

Ve starém Nette to fungovalo, jak je psáno, ale po aktualizaci projektu na nové Nette se začal uživatel odhlašovat random. Aby bylo jasno, nikdy jsem nenastavoval expiraci přihlášení pomocí setExpiration(), takže by podle dokumentace měla být tato expirace stejně dlouhá, jako expirace session, což mám v konfiguračním souboru nastaveno na 14 dní:

session:
	expiration: 14 days

Nikde jinde session expiraci nenastavuji.

Původně na starém projektu jsem si myslel, že jsem někde udělal chybu v aktualizaci na nové Nette.
Nedávno jsem ale založil nový projekt, kde se děje to samé. Aniž by člověk vypnul prohlížeč/počítač, tak se prostě náhodně odhlásí.
Vidím to i já v rámci Chromu, který si navíc drží data i po vypnutí, takže k tomuto fenoménu by nemělo docházet. Někdy se odhlásí zhruba za den a jindy stačí, když nechá zapnutý PC a jde jen na WC, koukne na video na YT atp. a když pak klikne na něco v aplikaci, tak je odhlášen.

Proč si myslím, že je problém se Session je ten, že toto není jediný problém, který nastává.
Taktéž se v dokumentaci k FlashMessagges píše, že se ukládají do session a jejich expirace je 30 sekund pro případný omylný refresh ze strany uživatele.
Což je pochopitelné, ale z nějakého důvodu se tento limit s každým refreshem prodlužuje, takže když se nastavilo například 5 flash messages, tak je při každém refreshi, který byl v kratším intervalu než 30 sekund musí uživatel manuálně zavírat a při pravidelném refreshi v kratších intervalech, než je 30s vidí vlastně tyto FlashMessages nekonečně dlouho, což je dost otravné.

U 2 problému upřímně nevím, jestli je chyba, nebo je prodloužení expirace při čtení z FlashMessages záměr, ale první problém je opravdu problém, protože potom věci, jako trackování, kdy se uživatel přihlásil do systému přestávají dávat smysl a navíc to uživatele otravuje a chodí E-maily se stížnostmi, že se musejí stále přihlašovat.

Dokonce ani nemusí být chyba v Session, ale jen v tom, jak s ní dané věci pracují, ale do hloubky jsem to netestoval.

Milo
Nette Core | 1283
+
+1
-

Na jakém OS? Na Linuxu bývá periodický task, který pravidelně session dir promaže. Zkus si nastavit vlastní adresář.

mystik
Člen | 284
+
+1
-

Pokud pouzivas systemove sessions PHP tak ty maji taky omezenou platnost (nastavenou v php.ini). I kdyz aplikace nastavi delsi system ty sessions po urcitem intervalu promazava.

Bulldog
Člen | 110
+
0
-

Díky za odpovědi.

@Milo Session dir mám nastavenou vždy vlastní, abych tyto problémy eliminoval. Konkrétně do ./temp/session/ a na promazávání mám nastavený vlastní CRON, který se spouští vždy o půlnoci, načte sessions a ty, které jsou starší, než 14 dní promaže. Ovšem problém setrvává i když můj cron na mazání vypnu, takže tím to taky nebude.
Děje se to na více typech operačních systémů. Tuhle možnost jsem eliminoval jako první tím, že jsem aplikaci zkoušel spustit na Winech a Ubuntu. Taktéž jsem zkoušel PHP spouštět na Apache, nginx a litespeed. Všude problém přetrvává.

@mystik koukl jsem na nastavení v PHP.ini a je tam v sekci session.gc_maxlifetime hodnota 1440 sekund, takže asi 24 minut. Jak poznám, jestli se používá tahle hodnota a ne ta z konfigu? Nic víc, než cestu ukládání souborů jsem nenastavoval a jedná se tedy o výchozí Nette implementaci.

Bulldog
Člen | 110
+
0
-

Tak 24 minut to nebude. Nastavil jsem si časovač na 30 minut a zkusil se přihlásit. Neodhlásilo mě to. Tedy čas pro odhlášení je delší, než těch 1440 sekund z PHP.ini

EDIT
Refresh po další hodině a zatím jsem přihlášen

EDIT 2
Po dalších 2 hodinách odhlášeno

Editoval Bulldog (31. 12. 2022 0:54)

Kamil Valenta
Člen | 752
+
0
-
  1. napsal bych si malý PHP skript (bez nette), který zapíše do sessiony a pak z ní bude periodicky číst, zjistíš, zda se sessiony nepromazávají mimo PHP skripty (cronem, dle php.ini, tuším i apache má na to direktivy)
  2. pokud to dle 1) bude žít, udělal bych v nette dvouakční presenter (bez přihlášení), v jedné akci zapsat do session, v druhé periodicky číst, zjistíš, zda neexpiruje celá sessiona
  3. až kdyby to žilo i dle 2), hledal bych chybu v user storage, ale tipuji, že to do 3) nedojde…

Editoval Kamil Valenta (31. 12. 2022 10:27)

mystik
Člen | 284
+
+1
-

Ta hodnota urcuje po jake dobe muze byt session smazana. V zavislosti na dalsich nastavenich se trvani muze lisit.

V default nastaveni mas 1% sanci ze se spusti promazani starych session pri requestu. Pokud se nespusti session zije dal.

Zkus v php.ini nastavit session.gc_probability na 0. Tim tenhle mechanismus vypnes.

Bulldog
Člen | 110
+
0
-

Díky vyzkouším oboje.

K @mystik mám ale ještě otázku.
Že se session nemaže pořád, ale náhodně chápu. Mazání pořád by ale mělo záviset na invalidaci ne?
Respektive chápu to tak, že pokud je v PHP.ini nastaveno session.gc_maxlifetime na 24 minut, tak to neznamená, že se session po 24 minutách vymaže, ale že se stane neplatnou a i když existuje fyzicky soubor se session, tak by mělo PHP vědět, že uběhlo 24 minut a data jsou neplatná a tedy v $_SESSION by ta data už být neměla ne?

Nebo se snad tato data načítají vždy, když existuje soubor a ten lifetime není invalidace, ale jen informace po jakém časovém úseku se mohou data náhodně smazat?

mystik
Člen | 284
+
0
-

Ano parametry session.gc_* jsou parametry garbage collectoru sessions. Tj. jen toho mechanismu, který je promazává po určité době, kdy nebyly použity. Nijak to už neřeší zda session obsahuje platná data apod. Jen jejich mazání aby se nehromadily staré sessions. Na určení platnosti se používají jiné mechanismy. Třeba cookie lifetime.

m.brecher
Generous Backer | 713
+
0
-

@Bulldog ve které verzi Nette ten problém vznikl ?

Bulldog
Člen | 110
+
0
-

Mystik. To je dost na prd, když ti to může mazat i platné sessions.

@mbrecher Nevím. Bylo to někde mezi 2 a 3
Ale podle této konverzace je možnost, že to vzniklo přechodem z PHP7.1 na PHP8.0 a Nette s tím nemusí mít nic společného.

mystik
Člen | 284
+
+4
-

@Bulldog: Tak musíš si to správně nastavit a pak ti to platné sessions mazat nebude. Nebo to vypnout pokud jako v Nette na to máš vlastní mechanismus.