Trvalé přihlášení – problém s cookies
- Pancus
- Člen | 14
Mám problém s trvalým přihlášením. Pro přihlášení do aplikace používám příklad z distribuce:
<?php
public function signInFormSubmitted($form) {
try {
$values = $form->getValues();
if ($values['remember']) {
$this->getUser()->setExpiration('+ 30 days', FALSE);
} else {
$this->getUser()->setExpiration('+ 30 minutes', TRUE);
}
$this->getUser()->login($values['email'], $values['password']);
$this->redirect('Homepage:');
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
?>
Pokud to chápu správně, tak by se měla platnost cookie „PHPSESSID“ nastavit na 30 dní. Ona má ale platnost pouze do konce sezení. V bootstrapu mám ještě nastaveno toto:
<?php
Environment::getSession()->setExpiration(30 * 24 * 60 * 60); // 30 days
?>
- Filip Procházka
- Moderator | 4668
Když nastavuješ platnost přihlášení, je ještě potřeba prodloužit
platnost session. Její platnost může skončit dřív, než platnost
SessionNamespace
, ve kterém je uživatel uložený.
- Pancus
- Člen | 14
Vyřešeno. Session nebyl jaksi nastartovaná. Do bootsrtrapu jsem přidal:
<?php
if (!$session->isStarted()) {
$session->start();
}
?>
Je to tak správně? Má to být v bootstrapu? Nebo někde jinde?
Toto mi přijde dost nejasně zdokumentované. Např. v Sandboxu v distribuci
(ze které jsem trvalé přihlášení okopnul) jsem nenašel startování
session. Chybí to tam?
Každopádně díky za nakopnutí!
- Aurielle
- Člen | 1281
Session by měla být startována automaticky, viz https://api.nette.org/…ion.php.html#97.
- kucix
- Člen | 33
Pancus napsal(a):
Vyřešeno. Session nebyl jaksi nastartovaná. Do bootsrtrapu jsem přidal:
<?php if (!$session->isStarted()) { $session->start(); } ?>
Je to tak správně? Má to být v bootstrapu? Nebo někde jinde?
Toto mi přijde dost nejasně zdokumentované. Např. v Sandboxu v distribuci (ze které jsem trvalé přihlášení okopnul) jsem nenašel startování session. Chybí to tam?Každopádně díky za nakopnutí!
Když jsem to použil, tak se vytvořilo přes 30000 session souborů a bylo
využito celých 16GB RAM a k tomu ještě skoro 10GB swap …
Jen dodám, že normálně je využito tak 5–7GB RAM a 0 SWAP
Má někdo nějaké jiné řešení ?
- kucix
- Člen | 33
nj, ale jak to vyřešit …
řeším dva problémy:
- když to není v bootstrapu, tak po zavření prohlížeče jsem automaticky odhlášen (ano mám v botstrapu nastavenou hlavní session a + 14 days)
- když to dám do bootstrapu, tak přihlášení vydrží, ale zabije to nakonec server … díky iowaitu
Napsat si ukládání do databáze .. o tom jsem přemýšlel, ale DB je už tak celkem dost vytížená.
PS: stránka, na které to řeším má cca 100 000 uživatelů za den,
500 000 zobrazení za den …
V měsíčním průměru je to něco mezi 16M a 17M zobrazení … takže by to
databázi určitě nepomohlo …
- Michalek
- Člen | 211
Řeším podobný problém, jen s o nulu kratším číslem. Jediné, na co jsem přišel, je rozvrstvit session do podadresářů, protože dle mýho zjištění největší problém dělá čtení tolika souborů v jednom adresáři. A snížit pravděpodobnost mazání starých. Pak zatížení serveru rapidně kleslo.
ini_set('session.save_path', '2;/var/www/session/'); // http://goo.gl/zRH3I
ini_set('session.gc_divisor', 10000);
- kucix
- Člen | 33
Stejně.. to je takové řešení … na prd …
pořád mi nejde do hlavy, proč musím obcházet startování session ve frameworku jeho manuálním startováním v bootstrapu…
Bez těch 3 řádků vše funguje jak má, uživatel je přihlášen, vše v pohodě.. až na to zavření prohlížeče, kdy ho to automaticky odhlásí …
Už přemýšlím i nad tím, jestli problém nebude v tom, že
v BasePresenteru v metodě startup()
volám $this->user = Environment::getUser();
- srigi
- Nette Blogger | 558
kucix napsal(a):
pořád mi nejde do hlavy, proč musím obcházet startování session ve frameworku jeho manuálním startováním v bootstrapu…
Nemusis. V bootstrap.php
staci iba
Environment::getSession()->setExpiration('+ 90 days');
. Zvysok
zariad podla mojho ACL tut. Takto to
ide v pohode (session vydrzi restart browsera), netreba session manualne
startovat. Moze sa vsak obcas objavit chyba
headers already sent
– pretoze, session sa staruje lazy. A ak
spravis echo na vystup… (vsak to pozname).
- kucix
- Člen | 33
Nepotřebuji ACL, řeším to trochu jinak
(Environment::getUser()->getIdentity()->data['rights']
)
A přihlašují se všichni, ne jen admini, ale všichni uživatelé.
Při stavu, kdy proběhne odhlášení při zavření prohlížeče byl kód cca takto:
- bootstrap –
Environment::getSession()->setExpiration("+ 14 days");
- BasePresenter – metoda startup():
$this->user = Environment::getUser();
, v zápětí$this->user->isLoggedIn();
dokonce 2× … podruhé v metoděcheckUser()
, kde vyberu z DB uživatele podle údajů zgetIdentity()->data[]
a pokud se liší, tak zavolám$this->user->login($username, $password)
(password je md5, nejsem blázen a nemám v session plaintext heslo …)
login mám přes svoji třídu – výtažek:
<?php
public function loginFormSubmitted(AppForm $form) {
try {
$values = $form->getValues();
$user = Environment::getUser();
$user->setExpiration( "+ 14 days", false);
$user->login($values['username'], MyHash::hash($values['password']));
...atd...
?>
Teď po přidání do bootstrapu toho nastartování, které je výše, uživatel zůstane přihlášený i po zavření prohlížeče, jen se generuje velké množství sessions
teď jsem ještě zkusil dát na konec bootrstrapu, za spuštění aplikace:
<?php
if(!Environment::GetUser()->isLoggedIn()){
Environment::getSession()->destroy();
}
?>
Ale to bude mít za následek jen to, že se pro nepřihlášeného (i robota) session na disku vytvoří a následně smaže… nebude takové množství souborů, ale stále je tu vysoký iowait díky vytváření sessions a jejich mazání…