Přesměrování pomocí backlink nefunguje při odkazu z e-mailu
- roman.campula
- Člen | 60
Zdravím,
narazil jsem na problém, který jsem tady ještě nenašel, že by
někdo řešil.
Zjednodušeně řečeno, mám presenter na zobrazení diskusního fóra, který je přístupný jen přihlášeným. Pokud jako nepřihlášený přejdu na adresu xxx.local/forum, dojde k přesměrování na přihlašovací formulář a po přihlášení zpět pomocí backlink na xxx.local/forum. To je OK. V Tracy je vidět přesměrování.
Stav Tracy po přesměrování na přihlašovací formulář:
https://pasteboard.co/J4Z2QBv.png
Já však pošlu e-mailem odkaz na xxx.local/forum. Po kliknutí na odkaz se spustí nová karta v Chrome, dojde k přesměrování na přihlašovací formulář, ale po přihlášení (úspěšném) jsem stále na stránce s přihlašovacím formulářem. V Tracy se přesměrování ztratí, tudíž je asi logické, že se není „kam vrátit“.
Stav Tracy po přesměrování na přihlašovací formulář:
https://pasteboard.co/J4Z2WCx.png
Jak docílit toho, aby se to také přesměrovalo na xxx.local/forum?
- Kamil Valenta
- Člen | 820
Myslím si hlavně, že chyba je už v návrhu, kdy se nepřihlášený uživatel přesměrovává pryč, aby se následně (s pomocí backlinku složitě a kdo ví jestli) vrátil zpět.
Nevím, kde a kdy vznikla tahle „móda“, ale zdá se mi špatná. HTTP je desítky let stejné a nejlépe je využívat věci tak, jak byly vymyšleny (a redirect pro nepřihlášeného uživatele to není).
- roman.campula
- Člen | 60
Tato traita je vložena do presenteru:
trait RequireLogedUserTrait {
function injectRequireLoggedUser() {
$this->onStartup[] = function () {
if (!$this->user->isLoggedIn()) {
if ($this->user->getLogoutReason() === Nette\Security\IUserStorage::INACTIVITY) {
$this->flashMessage($this->translator->translate("app.flashMessage.logoutInactivity"), "warning");
$this->redirect(":Web:Users:login", ["backlink" => $this->storeRequest()]);
}
else {
$this->flashMessage($this->translator->translate("app.flashMessage.loginRequired"), "warning");
$this->redirect(":Web:Users:login", ["backlink" => $this->storeRequest()]);
}
}
};
}
}
Takto je vytvořena komponenta s přihlašovacím formulářem (vytvoření samotného formuláře asi není nutné uvádět):
function createComponentLoginFormControl() {
$loginFormControl = $this->loginFormControlFactory->create($this->actualPresenter);
$loginFormControl["form"]->onSuccess[] = function () {
if (isset($this->backlink)) {
$this->restoreRequest($this->backlink);
}
};
return $loginFormControl;
}
Editoval roman.campula (22. 4. 2020 21:13)
- roman.campula
- Člen | 60
Vycházel jsem z https://doc.nette.org/…tore-request, a podle mě tam další redirect není potřeba. Jen v případě, že by backlink neexistoval, ale v mém případě vždy existuje. Každopádně jsem zkoušel obě varianty, ale výsledek je stejný.
A ještě jedna „záhada“ – z mobilního e-mailového klienta (Gmail) funguje vše bez problémů. Problém je jen na PC za použití různých prohlížečů i e-mailových klientů (vyzkoušeno z několika PC, stejný problém).
- David Matějka
- Moderator | 6445
napada me, ze mozna ten desktopovy klient, namisto toho, aby rovnou otevrel v prohlizeci tu stranku, tak zkusi provest request na ten link a otevre az tu stranku, na kterou to presmerovava. a request backlinku se ulozil do session toho email klienta a ne do session browseru.
mozna bys tam mohl dat jako fallback jeste nejaky urlBacklink, kam ulozis aktualni url a pouzijes to, pokud restoreRequest nezafunguje
- roman.campula
- Člen | 60
Díky za tipy. Nevím, zda je to úplně ideální, ale problém se zdá být vyřešen následovně:
Do přesměrování po zjištění nepřihlášeného uživatele jsem přidal
backlinkUrl
.
trait RequireLogedUserTrait {
function injectRequireLoggedUser() {
$this->onStartup[] = function () {
if (!$this->user->isLoggedIn()) {
if ($this->user->getLogoutReason() === Nette\Security\IUserStorage::INACTIVITY) {
$this->flashMessage($this->translator->translate("app.flashMessage.logoutInactivity"), "warning");
$this->redirect(":Web:Users:login", ["backlink" => $this->storeRequest(),
"backlinkUrl" => $this->getHttpRequest()->getUrl()->getAbsoluteUrl()]);
}
else {
$this->flashMessage($this->translator->translate("app.flashMessage.loginRequired"), "warning");
$this->redirect(":Web:Users:login", ["backlink" => $this->storeRequest(),
"backlinkUrl" => $this->getHttpRequest()->getUrl()->getAbsoluteUrl()]);
}
}
};
}
}
Do formuláře na přihlášení jsem přidal skryté pole s
backlinkUrl
(předává se do komponenty při jejím
vytvoření).
$form->addHidden("backlinkUrl", $this->backlinkUrl);
Po odeslání formuláře se v případě selhání přesměrování přes
klasický backlink
zkusí přesměrovat pomocí
backlinkUrl
.
function createComponentLoginFormControl() {
$loginFormControl = $this->loginFormControlFactory->create($this->actualPresenter, $this->getParameter("backlinkUrl"));
$loginFormControl["form"]->onSuccess[] = function () use ($loginFormControl) {
if (isset($this->backlink)) {
$this->restoreRequest($this->backlink);
}
if (isset($loginFormControl["form"]["backlinkUrl"]->value)) {
$this->redirectUrl($loginFormControl["form"]["backlinkUrl"]->value);
}
};
return $loginFormControl;
}