Nefungující redirect
- jakubroz
- Člen | 16
Ahoj,
s touto situací jsem se setkal poprvé.
V startup() mam pro ověření jestli je uživatel přihlášen(je jenom jedna uroven uživatele, neni potřeba Role)
Tento kod:
if ($user->isAuthenticated()) {
$this->template->status = 'Prihlášen uživatel: '. $user->getIdentity()->getName();
} else {
$this->template->status = 'Uživatel není přihlášen';
Environment::getHttpResponse()->redirect($this->link('User:login'));
}
Redirect se jakoby provede ale login() se nenačte. Firefox mi vyhodí chybu:
The page isn't redirecting properly
Firefox has detected that the server is redirecting the request for this address
in a way that will never complete.
Nevíte co to může způsobovat? Prosím o radu.
Díky moc.
- kravčo
- Člen | 721
HttpResponse::redirect() nastavuje len hlavičku Location:
, keby
si za jeho volanie pripísal exit;
, malo by to fungovať.
Určite lepším riešením je použiť na redirect vyšší mechanizmus – priamo prezenter:
if ($user->isAuthenticated()) {
$this->template->status = 'Prihlášen uživatel: '. $user->getIdentity()->getName();
} else {
$this->template->status = 'Uživatel není přihlášen';
$this->redirect('User:login');
}
V tomto prípade exit;
nie je potrebný, keďže v prezenteri
je redirect obsluhovaný výnimkami…
- jakubroz
- Člen | 16
Máte pravdu, opravdu jsem tam nechal to $this->link().
Ale když jsem to dal bez toho, tak vyskočí stejná chyba jako předtim. Ta z webového prohlížeče.
Zkusil sem to třeba v safari a to píše: Too many redirects occurred trying to open “http://localhost:8888/project/admin/document_root/”. This might occur if you open a page that is redirected to open another page which then is redirected to open the original page.
- Blizzy
- Člen | 149
Login do administrace je pěkně popsaný v příkladech (examples) v distribuci v příkladu CD Collection.
Já mám udělaný BaseAdminPresenter, který potom dědí presentery v Admin modulu, vypadá takto (není to ještě úplně dokonalé, ale je to funkční):
abstract class BaseAdminPresenter extends BasePresenter {
protected function startup() {
$user = Environment::getUser();
if (!$user->isAuthenticated()) {
$backlink = $this->application->storeRequest();
$this->redirect('Auth:login', $backlink);
}
parent::startup();
}
}
EDIT: Ten tvůj template->status
by se asi měl řešit
pomocí flashMessage
.
Editoval Blizzy (13. 8. 2009 17:22)
- Blizzy
- Člen | 149
Auth presenter vypadá shruba takto (je to z větší části dělané podle toho příkladu v distribuci):
class Admin_AuthPresenter extends BasePresenter {
/** @persistent */
public $backlink = '';
public function actionLogout() {
Environment::getUser()->signOut();
$this->flashMessage('Byli jste odhlášeni.');
$this->redirect('Auth:login');
}
public function actionLogin($backlink) {
$this->template->title = 'Příhlášení';
}
/********************* loginForm *********************/
public function createComponentLoginForm() {
...
}
public function loginFormSubmitted($form) {
try {
$user = Environment::getUser();
$user->authenticate($form['username']->value, $form['password']->value);
$this->application->restoreRequest($this->backlink);
$this->redirect('Dashboard:');
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
}
EDIT: V podstatě to pracuje tak, že při pokusu zajít do adimistrační
části (presentery založené na BaseAdminPresenter) nepřihlášeného
uživatele, se přesměruji na Login autentizačního prezenteru, ten dostane
serializovaný původní request a po správném vyplnění autentizačního
formuláře se tento request ($backlink) znovu obnoví (v tom případě
vyhodí výjimku), pokud se request neobnoví (není vyhozena výjimka), provede
se $this->redirect('Dashboard:');
.
Editoval Blizzy (13. 8. 2009 17:05)
- Blizzy
- Člen | 149
To je jenom název modulu, na tom ani tak nezáleží, a pokud je modul jenom jeden, dá se říct, že je používání modulů zbytečné.
Jde o to, že všechny presentery ke kterým by měli přistupovat jen autentikovaní uživatelé jsou potomky BaseAdminPresenter, ve kterém je metoda startup(), která v případě neautentikovaného uživatele uloží request (do proměnné $backlink) a pošle ho uživatele na autentikaci do Auth:Login.
AuthPresenter je jediný presenter, který tuto metodu nedědí (protože by se přihlašování zacyklilo, když by tam přišel nepřihlášený uživatel). Jeho úkol v případě akce Login je zobrazení formuláře, který při zpracování autentikuje uživatele a přesměruje ho na původní request (který získá z persistentního parametru $backlink).
Editoval Blizzy (13. 8. 2009 17:23)
- Blizzy
- Člen | 149
Já tuto metodu startup()
mám v abstraktní třídě
BaseAdminPresenter, aby tuto metodu mohli zdědit všechny presentery, které
vyžadují autentikovaného uživatele.
BaseAdminPresenter není „skutečný“ presenter, má jenom tu funkci, že ho někdo zdědí, proto je to abstraktní třída, která nemůže mít instance.