Chyba v Session – Automatické odhlašování a automatické prodlužování expirace session u FlashMessages
- Bulldog
- Člen | 110
Ahoj,
v 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ředlogin()
.
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.
- Bulldog
- Člen | 110
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
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 | 820
- 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)
- 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
- 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 | 312
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
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 | 312
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.