Přesměrování pomocí backlink nefunguje při odkazu z e-mailu

roman.campula
Člen | 60
+
0
-

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?

David Matějka
Moderator | 6445
+
0
-

jak pracuješ s tím backlinkem?

Kamil Valenta
Člen | 748
+
0
-

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

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)

MajklNajt
Člen | 470
+
0
-

možno sa mýlim, ale podľa mňa $this->restoreRequest($this->backlink); nespúšťa redirect – prípadne ma niekto opravte…

roman.campula
Člen | 60
+
0
-

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

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

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;
  }