Redirect a AJAX při znovuotevření prohlížeče po expiraci přihlášení
- LeonardoCA
- Člen | 296
Mám nastavenou expiraci přihlášení na 30 min, pokud byl poslední požadavek Ajaxový, zavřu prohlížeč a otevřu ho až po expiraci přihlášení (s tím, že nezavírám tab s aplikací), místo redirectu na login stránku se zobrazí json v prohlížeči.
Je to logické, protože aplikace posílá redirect do json, které se zpracovává v nette.ajax.js ale protože stránka není načtená a tím pádem ani žádné obslužné js, tak se json zobrazí. (pokud k expiraci přihlášení dojde pri otevřeném prohlížeči, tak dojde korektně k redirectu na přihlášení a pak zpátky na předešlou stránku)
v SecurePresenter mám toto (ale myslím, že problém je někde úplně jinde)
protected function startup()
{
parent::startup();
if (!$this->user->isLoggedIn()) {
if ($this->user->getLogoutReason() === \Nette\Security\User::INACTIVITY) {
$this->flashMessage('You were inactive for longer period! For security reasons you were signout.', 'warning');
} else {
$this->flashMessage('Please sign in.', 'warning');
}
if ($this->getParameter('nobacklink'))
{
$this->redirect('Auth:default');
} else {
$this->redirect('Auth:default', array('backlink' => $this->getApplication()->storeRequest('+1 minutes')));
}
}
}
Myslím, že mám někde nějakou hloupou chybu, ale netuším kde. Napovíte kde ji hledat?
Editoval LeonardoCA (23. 9. 2012 12:59)
- pawouk
- Člen | 172
No a proč nedáš do té akce která vrací ten json podmínku zda je uživatel přihlášen a pokud ne tak ho přesměruješ na přihlašovací stránku? Když pak nastartuješ prohlížeč a nebudeš přihlášen tak se zavolá akce a ta ho přesmětruje ne? Navic by jsi měl u každého ajax vystupu kontrolovat v presenteru zda jde o ajax metodou isAjax() a tím by se toto také nikdy nemělo stát.
- LeonardoCA
- Člen | 296
Musím to ošetřit přímo v tom secure presenteru, dál se to stejně nedostane.
Jen mne napadlo, jestli jsem svým kódem nerozbil nějakou Nette funkcionalitu, která tohle ošetřuje a nebo jestli si to musím ošetřit sám… dám vědět k čemu dospěju.
Editováno:
Myslím, že problém je při použití redirectu presenter se ptá Http\Request jde li o Ajax a na základě toho buď přesměruje nebo pošle payload. Já potřebuji explicitně definovat, že i v případě, že je to Ajax volání, tak to má redirectnout „natvrdo“ a teď mne nenapadá jiné řešení než unset(Header(‚X-Requested-With‘) pokud je to nějak možné.
A to se mi právě nezdá, proto píšu na fórum.
A nebo pak poslat sám přímo response.
Editoval LeonardoCA (23. 9. 2012 21:21)
- LeonardoCA
- Člen | 296
Tak jsem problém vyřešil takto:
protected function startup()
{
parent::startup();
if (!$this->user->loggedIn) {
if ($this->user->logoutReason === \Nette\Security\User::INACTIVITY) {
$this->flashMessage('You were inactive for longer period! For security reasons you were signout.', 'warning');
} else {
$this->flashMessage('Please sign in.', 'warning');
}
if ($this->isAjax()) {
$url = $this->link('Auth:default', array('backlink' => $this->getApplication()->storeRequest('+1 minutes')));
$this->sendResponse(new \Nette\Application\Responses\RedirectResponse($url));
} else {
$this->redirect('Auth:default', array('backlink' => $this->getApplication()->storeRequest('+1 minutes')));
}
}
}
Json se nezobrazí a dojde k přesměrovnání na přihlášení a pak zpátky. Ale pořád se mi nezdá jestli jsem neměl/nemám chybu jinde, třeba v nastavení expirace v http headers. Přijde mi to kostrbaté.
Nesetkal se s tím už někdo?
@pawouk : Presenter poznal při redirect, že jde o Ajax, tak jak jsem popsal výše, ale poslal redirect přes json, v tom je problém… při kliknutí v aplikaci po expiraci přihlášení se to chová správně, ale nechovalo se to správně po zavření a znovuotevření prohlížeče pokud byl poslední request ajaxový.
Editoval LeonardoCA (23. 9. 2012 21:59)
- LeonardoCA
- Člen | 296
Tak jak jsem tušil problém byl úplně jinde. A to čistě v nastavení expirace ajaxových požadavků. Projevovalo se to jen v některých případech. Konkrétně ve firefoxu pokud mi expirovalo přihlášení v neaktivním tabu a po znovuotevření prohlížeče s více taby jsem přepnul na tab s nette aplikaci.
Nejjednodušší řešení je přidat do nastavení ajaxové komunikace na straně js cache: false
Jinak se to dán řešit nastavením hlaviček, ale to je spousta práce a hlídání navíc. ‚Expiration: –1‘, atd…