Expiration help
- carnaby
- Člen | 7
Z urcitych dovodou potrebujem nastavit aby uzivatel mohol byt dlho prihlaseny bez toho aby nieco robil a nemusel sa znova prihlasovat.
nastavil som pre uzivatela aj
$session->setExpiration(86400, FALSE);
co je jeden den.
neviem preco ale nech tam dam akekolvek cislo tak po uplinuti caa 30min mi
expiruje a musi sa prihlasit znova.
zaujimave je to ze ked menim systemovy cas servera tak to funguje presne ale
ako nahle realne cakam tak to expiruje respektive
$user->isAuthenticated()
vrati FALSE
.
budem vdacny za akukolvek pomoc ci radu.
- romansklenar
- Člen | 655
Pokud chceš aby to fungovalo takto, musíš nastavit i expiraci Nette\Web\Session na stejnou hodnotu jako je expirace přihlášení, protože používají tuším stejný namespace či z nějakého takového důvodu. Čili:
$session = Environment::getSession();
$session->setExpiration(86400, FALSE);
Ještě můžeš zkusit nastavit uživateli nějaký namespace:
$user->setNamespace('myApp');
$user->setExpiration(86400, FALSE);
PS: žádosti o pomoc do hlášení chyb nepatří, přesouvám.
PPS: sorry špatně jsem si to napoprvé přečet
- carnaby
- Člen | 7
napriek tomu stale expiruje.
mozno to mam na zlych miestach hmm
<?php
Environment::getSession()->setExpiration(86400,FALSE);
?>
mam v bootstrap.php
a
<?php
$user = Environment::getUser();
$user->authenticate($username, $password);
$user->setNamespace('myApp');
$user->setExpiration(86400, FALSE);
?>
mam v AuthPresenter.php → actionLogin
testujem to uz hodne dlho,(1 test == 30min :) no nech tam napisem cokolvek tak po tych caa 30min session proste „zabudne“
- romansklenar
- Člen | 655
V nastavení session je výchozí hodnota expirace nastavena na 3h. Nikde jinde nic v Nette co by nějak přenastavovalo hodnotu nevidím. Co nastavení PHP?
Klidně by to mohlo jít všechno do bootstrapu (podle toho jak se získává uživatel):
Environment::getSession()->setExpiration(86400, FALSE);
$user = Environment::getUser();
$user->setNamespace('myApp');
$user->setExpiration(86400, FALSE);
Ještě pozor na jednu chybu: v aplikaci se mi stávalo, že jsem nějak neměl ošéfované session a pokud jsem byl v prohlížeči lognutý na svůj web a zároveň jsem měl někde otevřený akrabat tak to blblo.
- _Martin_
- Generous Backer | 679
romansklenar napsal(a):
Ještě pozor na jednu chybu: v aplikaci se mi stávalo, že jsem nějak neměl ošéfované session a pokud jsem byl v prohlížeči lognutý na svůj web a zároveň jsem měl někde otevřený akrabat tak to blblo.
Na řešení jsi už nejspíš přišel, ale pro ostatní: pokud je na jednom serveru více Nette aplikací, je potřeba udělat jedno z následujících nastavení
- nastavit každému projektu vlastní složku pro session soubory
- používat v session jmenné prostory (pro přihlašování lze jednoduše
použít
$user->setNamespace('jmeno-aplikace');
)
První způsob je lepší, neboť si člověk nemusí hlídat jmenné prostory (tuším, že v druhém případě si bude Nette v session uchovávat některé společné interní údaje i při použití jmenných prostorů – kdyžtak mě prosím opravte), nicméně ne vždy může být krok a) umožněn, takže b) je lepší, než nic :)
- _Martin_
- Generous Backer | 679
phx napsal(a):
Neni to nesmysl? Kazdy aplikace/uzivatel by le mit svoje SESSION a o premazavani by se mel starat PHP ne? Aby kazda nova session byla unikatni. Nebo si Nette nejak vynucuje konkretni tvar SESSION_ID?
Session ID je posílané v cookie. A ve výchozím nastavení (nevím, zda jde změnit, možná ano) posílá prohlížeč cookie, pokud jde o stejný server. Pokud mám na serveru dvě Nette aplikace, v první se přihlásím a následně tím samým prohlížečem půjdu do druhé aplikace, pošle prohlížeč cookie automaticky a Nette použije session vytvořenou v první aplikace.
- nAS
- Člen | 277
_Martin_ napsal(a):
Session ID je posílané v cookie. A ve výchozím nastavení (nevím, zda jde změnit, možná ano) posílá prohlížeč cookie, pokud jde o stejný server. Pokud mám na serveru dvě Nette aplikace, v první se přihlásím a následně tím samým prohlížečem půjdu do druhé aplikace, pošle prohlížeč cookie automaticky a Nette použije session vytvořenou v první aplikace.
Pro jakou doménu a relativní cestu se session nastavuje slouží setCookieParams. Nebo mi něco uniká?
- _Martin_
- Generous Backer | 679
nAS napsal(a):
Pro jakou doménu a relativní cestu se session nastavuje slouží setCookieParams. Nebo mi něco uniká?
Skvěle, takže nastavit jde. Nicméně ve výchozím nastavení se na cestu nehraje.
phx napsal(a):
Cookies se tusim v vychozim nastaveni rozlisuji dle domeny! Takze jedine 2 aplikace na stejne domene.
Jj, špatně jsem se vyjádřil, slovy stejný server jsem myslel stejná doména.
- tom
- Člen | 171
Snažím se v session nastavit si 2 namespace a pro každý z nich jinou expiraci. První aby měl třeba 14dní a ten druhý aby expiroval po zavření prohlížeče. Jde něco takové udělat?
Zkouším to takto
<?php
$this->session = Environment::getSession();
$this->session->setSavePath(dirname(__FILE__) . '/../sessions/');
$this->namespace1 = $this->session->getNamespace('ns1');
$this->namespace1->setExpiration(1209600); // 14 dni
if (!isset($this->namespace1->prom1)) {
$this->namespace1->prom1 = array();
}
$this->namespace2 = $this->session->getNamespace('ns2');
$this->namespace2->setExpiration(0);
if (!isset($this->namespace2->prom2)) {
$this->namespace2->prom2 = array();
}
?>
ale k očekávanému výsledku to nevede – oba namespace zůstávají naplněny i po vypnutí prohlížeče. Lze to nějak vyřešit nebo se pokouším o něco co je z principu blbost?
Díky moc.
- _Martin_
- Generous Backer | 679
Implementovat by to pravděpodobně šlo, ale vyžadovalo by to používat pro každý jemnný prostor vlastní cookie. Což v PHP implementaci není možné, musela by se tedy napsat vlastní správa session.
Jednodušší by tedy bylo, pokus bys posílal vlastní cookie (nějakým způsobem navázanou na session), které nastavíš expiraci po uzavření prohlížeče – a na základě této cookie ručně mazal jmenný prostor.
- pmg
- Člen | 372
Jedná se o cookie, jejíž platnost Nette nastaví do zavření prohlížeče. Zvláštní cookie se musí použít proto, že expirace session je nastavena na čas v sekundách. Uživatel pak může být odhlášen a přitom neztratí data v session. Zatím se klíč používá jen pro přihlášení uživatele, bylo by ho ale možné zohlednit pro jednotlivá namespaces.
- David Grudl
- Nette Core | 8218
Ve třídě User tento mechanismus existuje, přenést ho do Session nebude problém. Jen tam vznikne teoretická nekompatibilita, setExpiration(0) v tuto chvíli ruší expiraci, nově by ji nastavil do zavření prohlížeče.
Zkusil jsem to implementovat, můžete to vyzkoušet.
- Jan Jakeš
- Člen | 177
Pokud jde o dlouhodobé přihlášení, tak zdá se, že toto funguje:
(bootstrap.php)
$session = Environment::getSession();
$session->setExpiration(1209600);
$user = Environment::getUser();
$user->setExpiration(1209600, FALSE);
Doba nastavená na dva týdy, přihlásil jsem se dnes kolem poledne a i po opakovaném vypnutí prohlížeče zůstává uživatel stále přihlášen…
S těmi namespaces jsem to zatím nezkoušel.
- ales.kafka
- Člen | 34
Pár dní si pohrávám s Nette, protože bych na něm chtěl postavit větší projekt. Nicméně, momentálně jsem se zasekl na expiraci přihlášení uživatele.
Rád bych, aby si uživatelé mohli při přihlašování zvolit, zda mají být přihlášení trvale nebo zda je odhlašovat při vypnutí prohlížeče. Takže v bootstrap.php mám definováno toto:
<?php
// nastaveni session
$session = Environment::getSession();
$session->setExpiration("+ 7 days");
$session->setSavePath(APP_DIR . '/sessions/');
// nastaveni uzivatele
$user = Environment::getUser();
$user->setAuthenticationHandler(new MyAuthenticator);
$user->setNamespace('user');
// $user->setExpiration("+ 7 days", FALSE);
?>
A ve zpracovávání LoginPresenter pak mám
<?php
$values = $form->getValues();
$user = Environment::getUser();
// set expiration
if ($values['remember']==true)
$user->setExpiration("+ 7 days", FALSE);
else
$user->setExpiration("+ 30 minutes");
?>
No a situace je taková, že v tomto případě mě to vždy po zavření prohlížeč odhlásí. V případě, že odkomentuju v bootstrap.php řádek $user->setExpiration(„+ 7 days“, FALSE); , tak mě to pokaždé nechá přihlášeného. Zkoušel jsem snad všechny možnosti i v různých prohlížečích, ale chování je pořád stejné. Je to třeba tím, že $user musí být nastavený ještě před $application->run(); ?
Editoval ales.kafka (3. 6. 2009 15:04)
- ales.kafka
- Člen | 34
David Grudl napsal(a):
Mělo by to být opraveno, můžeš to prosím vyzkoušet?
Skvěle, funguje jak má. Díky
- marek.dusek
- Člen | 99
Muzu se jen zeptat, v jakem poradi kde musi byt co uvedeno? Zkousim udelat totez a nastaveni $user->setExpiration() je ignorovano, tj. neco delam blbe ;)
- David Grudl
- Nette Core | 8218
$user->setExpiration("+ 3 days")
se volá před
$user->authenticate($username, $password);
V každém bootstrapu je potřeba nastavit
$session = Environment::getSession();
$session->setExpiration("+ 7 days"); // doba musí být minimálně taková, jako nastavená expirace.
- David Grudl
- Nette Core | 8218
Jak ale na začátku skriptu v bootstrapu zjistit nejvyšší expiraci? (nebo dejme tomu klidně i v průběhu skriptu – nikdy se nevolají všechny namespaces)
- David Grudl
- Nette Core | 8218
Na školení učím lidi nastavovat expiraci na 7 nebo 14 dní. To je asi nejsnažší cesta.
- theo
- Člen | 57
David Grudl napsal(a) na 1. stránce:
Mělo by to být opraveno, můžeš to prosím vyzkoušet?
Ať dělám co dělám, vždycky mi nastaví expiraci session za půl roku. V
index.php
mám:
<?php
...
// nastaveni session
$session = Environment::getSession();
$session->setSavePath(APP_DIR.'/sessions/');
$session->setCookieParams('/', Environment::getVariable('domain'), FALSE);
$session->setExpiration('+6 months', FALSE);
// nastaveni uzivatele
$user = Environment::getUser();
$user->setAuthenticationHandler(new MyAuthenticator);
//$user->setExpiration('+6 months', FALSE);
...
?>
a v UserPresenter.php
(obstarává přihlášení, odhlášení
a další věci související s uživatelem) v metodě
actionLogin
:
<?php
...
// nekde v konstruktoru predka je
$this->user = Environment::getUser();
...
// pokud uzivatel chce byt trvale prihlaseny
if ($data['zapamatovat'] === TRUE) {
// session vyprsi po roce, uzivatel mezitim muze zavrit okno
$this->user->setExpiration('+6 months', FALSE);
} else {
// session vyprsi po roce, nebo zavrenim okna
$this->user->setExpiration('+6 months');
} // if
// provedeme autentizaci
// predani db handleru neni sice moc ciste, ale pro moje ucely postacujici
$this->user->authenticate($data['login'], $data['heslo'], $this->db);
...
?>
Na další stránce po přihlášení mám pak dump objektu
user
, ve kterém si sice přečtu, že user má v session
nastaveno "expireBrowser" => FALSE
(v případě, že
$data['zapamatovat'] == TRUE
), resp.
"expireBrowser" => TRUE
(v případě, že
$data['zapamatovat'] == FALSE
), ale to je vše.
Když si ve FF podívám na odpovídající cookie, tak je tam vždy nastaveno datum expirace za půl roku (v případě, že si přihlášení nemá pamatovat tam má být místo toho něco ve smyslu „do konce relace“).
Pro pořádek verze Nette je 0.9.2 (revision b9fd602 released on 2009–11–12) pro PHP 5.2 (přiznávám, že ho provozuju na PHP 5.3, ale to kvůli tomu, že jsem ani za zlaté tele nebyl schopný se s ním domluvit ohledně namespaců, to by ale nemělo mít asi vliv).
Jsem natvrdlý, nebo je chyba jinde?
Editoval theo (23. 12. 2009 18:36)