Expiration help

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

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

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

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

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

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í

  1. nastavit každému projektu vlastní složku pro session soubory
  2. 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 :)

phx
Člen | 651
+
0
-

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?

_Martin_
Generous Backer | 679
+
0
-

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

_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á?

phx
Člen | 651
+
0
-

Cookies se tusim v vychozim nastaveni rozlisuji dle domeny! Takze jedine 2 aplikace na stejne domene.

_Martin_
Generous Backer | 679
+
0
-

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

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.

pmg
Člen | 372
+
0
-

Teoreticky by to možné bylo, ale není to implementované.

tom
Člen | 171
+
0
-

pmg napsal(a):

Teoreticky by to možné bylo, ale není to implementované.

a je možné zařadit to do seznamu Feature Requests pro Davida? Díky :)

_Martin_
Generous Backer | 679
+
0
-

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

Myslím, že není nutné používat zvláštní cookie pro každé namespace. Použije se jeden nette-authkey s platností do zavření prohlížeče a při její expiraci se expirují všechny namespaces, které měly nastavenou expiraci na nulu.

_Martin_
Generous Backer | 679
+
0
-

Co přesně je nette-authkey? Vím jen, že takovou cookie Nette posílá při autentifikaci.

pmg
Člen | 372
+
0
-

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.

_Martin_
Generous Backer | 679
+
0
-

Díky, to je chytré. Uvidíme, co na to Davídek.

Jan Jakeš
Člen | 177
+
0
-

Byla tu vůbec zodpovězena původní otázka? Tedy jak v nette vyřešit trvalé (dlouhodobé) přihlášení uživatele?

David Grudl
Nette Core | 8218
+
0
-

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

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.

tom
Člen | 171
+
0
-

David Grudl napsal(a):

Zkusil jsem to implementovat, můžete to vyzkoušet.

Zda se ze funguje, diky :)

ales.kafka
Člen | 34
+
0
-

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)

David Grudl
Nette Core | 8218
+
0
-

Mělo by to být opraveno, můžeš to prosím vyzkoušet?

ales.kafka
Člen | 34
+
0
-

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

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

$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.
redhead
Člen | 1313
+
0
-

Davide, nešlo by, že by se expirace session automaticky nastavovala podle nejvyšší zadané expirace nějaké namespace?? Třeba i volitelně přes nějakou option proměnnou.

David Grudl
Nette Core | 8218
+
0
-

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)

redhead
Člen | 1313
+
0
-

pravda, to mi nějak nějak nedošlo

PetrP
Člen | 587
+
0
-

A co kdyby při nastavení expirace v namespace zkontrolovalo jestli není větší nez „globální“ a případně to vyholo chybku?

David Grudl
Nette Core | 8218
+
0
-

Na školení učím lidi nastavovat expiraci na 7 nebo 14 dní. To je asi nejsnažší cesta.

theo
Člen | 57
+
0
-

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)