Formulář POST GET data v url

mimacala
Člen | 113
+
0
-

Ahojte,
mám jednoduchý formulář, ale po redirectu mi to stejně hodí do URL údaje což není moc bezpečné :/
Mohl by mi někdo prosím poradit jak schovat údaje před uživatelem ? :)
Děkuji

function createComponentPocetdnu(): Form
        {
        $form = new Form;
        $form->setMethod('POST');
        $form->addText('hledat', 'dny:')
            ->setRequired('Zadejte prosím');


        $form->addSubmit('vyhledej', 'vyhledej');
        $form->onSuccess[] = [$this, 'Hledejdny'];
        return $form;
        }

         public function Hledejdny(Form $form, $data): void
         {
              $this->redirect("Dashboard:starsireklamace", 1,$data->hledat);
         }
<form method="post" class="form-inline float-end" n:name="pocetdnu">
                 <table>
                    <tr>
                        <td> <input type="search" id="search" value="" n:name="hledat" class="form-control mr-sm-2"
                         placeholder="Zadejte počet dní"></td>
                        <td> <button n:name="vyhledej" type="submit" class="btn btn-primary">Zobrazit</button></td>

                    </tr>
                 </table>
            </form>
Pepino
Člen | 245
+
+1
-

@mimacala redirect je GET. Zpracuj ten formular v te fci hledejdny nebo pouzij misto redirectu forward.

mimacala
Člen | 113
+
0
-

Forward funguje díky,
ale vyskytl se problém v tom, že pokud odešlu formulář poprvé vše je ok a url není vidět, ale pokud odešlu formulář znova url se již zobrazí se zadaným počtem dní :/ … To nechápu

  public function renderStarsireklamace(int $page = 1, int $dny = 30) // zobrazuje přehled všech reklamací
   {


      $reklamace2 = $this->db->table($this->ZjistiTabulku())
                             ->where("datum_vytvoreni <= CURRENT_DATE() - INTERVAL $dny DAY AND aktivni = '1'")
                             ->order("datum_vytvoreni DESC");

      $lastPage = 0; // poslední stránka
      $this->template->reklamace = $reklamace2->page($page,10,$lastPage);


      $this->template->page = $page;
      $this->template->lastPage = $lastPage;

   }
Marek Bartoš
Nette Blogger | 1146
+
+3
-

Obecně vzato:

POST – ukládáš data do databáze, vygeneruje se ti ID záznamu, přesměrováváš na URL s ID záznamu
GET – nic neukládáš, data jsou v URL, nejspíš jde o vyhledávání

Tvůj formulář vypadá jako vyhledávání, proč by nebylo bezpečné mít zadaná data v url?

mimacala
Člen | 113
+
0
-

Ahoj moc děkuji z objasněni :)
Tady mám třeba formulář, kde si potřebuji přeposlat ID uživatele, na to je již potřeba brát ohled.
Prosím jakým způsobem by šlo bezpečně přeposlat ID uživatel přes formulář, aby o tomto údaji uživatel nevěděl :)
Chápu, že je to nejspíše banální záležitost..

<tbody>
    {foreach $uzivatele as $u}
    <tr>


      <td>{$u->email}</td>
      <td>{$u->jmeno}</td>
      <td>{$u->prijmeni}</td>
      <td>{$u->telefon}</td>
        <td><input type="submit" value="Změnit heslo" class="btn btn-warning"></td> // toto ještě není
 <form n:name="upravitUzivatele"> // tady začíná formulář
 <td>{$u->id}</td> // tady je ID uživatele, ale nechci jej zobrazovat v tabulce ani vkládat do inputu pro pozdější přeposlání
      <td><input type="checkbox" n:name="mazat" {if $u->mazat == "true"}checked="checked"{else}{/if}></td> //tady kontrola hodnoty
      <td><input type="checkbox"  n:name="otevirat" {if $u->otevirat == "true"}checked="checked"{else}{/if}></td> //tady kontrola hodnoty

      <td>
          <a n:href="SmazatUzivatele $u->id" class="btn btn-danger">Smazat</a>
      </td>
          <td><input type="submit"  n:name="ulozit" value="Uložit změny" class="btn btn-success"></td>//tady tlačítko na odeslání formu.
        </form> // konec formuláře
    </tr>
    {/foreach}
  </tbody>
 public function createComponentUpravitUzivatele() :Form
    {
        $form = new Form;
            $form->addCheckbox("otevirat");
            $form->addCheckbox("mazat");
            $form->addSubmit('ulozit');
            $form->onSuccess[] = [$this, 'ulozit'];
        return $form;
    }

    public function ulozit(Form $form, $data)
    {
        //tady data zpracuji, k danému uživateli podle jeho ID, ale nevím jak si ID přeposlat ve formuláři.
    }



Editoval mimacala (16. 5. 2022 20:51)

Pepino
Člen | 245
+
0
-

@mimacala když nechceš zobrazovat ID tak přidej do tabulky v DB nějaký jiný unikátní identifikátor, který budeš používat. Nicméně nevidím důvod proč ID nepoužívat/skrývat. Jestli ti jde o to, aby uživatel needitoval/smazal jiného, tak to je třeba řešit jinak.

Poslat ID můžeš buď v URL nebo <input type="hidden" value="{$u->id}">.

Polki
Člen | 553
+
0
-

@Pepino Pokud programuješ správně, tak ID v aplikaci vůbec není vidět a formuláře si ho nijak nemusí předávat.
Obecně proč ID nesmí jít vidět taky nechápu. Nějaké důvody jsou takové, že lidi jako ID používají nějaký counter, takže může člověk jednoduše změnou ID změnit cizí článek například.
Podle mě to je ale holý nesmysl, protože vždy, když odesíláš formulář, nebo přecházíš na nějakou URL, tak na pozadí probíhá ověření, jestli jsi schopný obsah na této adrese vidět, nebo editovat danou věc atp…

Hodně to propagují zastánci UUID, protože prý UUID je unikátní změť znaků, které nikdo neodhadne a nemůže tak jít na jiný článek, nebo editovat jiný post, než na jaký má odkaz. Jenže i tak prostě člověk musí to ověření na pozadí udělat, jelikož URL se dá ukrást, BruteForcenout atp. Když se člověk přihlásí na veřejné kavárně na kiosku nebo tak a ne pod anonymním režimem, tak v historii najdeš všechny url a pak je radost to měnit, takže Bezpečnostní hledisko 0…

Proto se musí i v případě použití UUID toto ověřování dělat, tedy z tohohle hlediska je úplně jedno, jestli použiješ UUID, ID jako int nebo co jiného…

Obecně ale souhlas s tím, že Přenášet ID v rámci Hiden inputů je na prd. Protože pak musíš dělat ověření při odeslání formuláře, jestli je uživatel oprávněn toto měnit, protože hidden input se dá přepsat.
Pokud to uděláš správně a ID vůbec nepřenášíš, jen si jej pamatuješ na pozadí, tak víš, že jej nikdo nepřepsal a tedy ho nemusíš kontrolovat. Jediné, co se tím pádem musí kontrolovat je, jestli má uživatel přístup na danou editační stránku a na to stačí Action metoda presenteru a nemusíš vůbec tvořit formulář. :)

Proto by měly formuláře být stavěny tak, aby se žádný unikátní ID/něco jiného nepřenášelo a přenášela se jen data, která chci editovat..

Editoval Polki (17. 5. 2022 9:21)

Kamil Valenta
Člen | 752
+
+5
-

Polki napsal(a):

Pokud to uděláš správně a ID vůbec nepřenášíš, jen si jej pamatuješ na pozadí…

„Na pozadí“ ale nemyslíš v sessioně, že ne?
Naopak zcela ideální je přenášet ID v URL. Sice se hodnota dá podvrhnout stejně snadno jako v hiddenu, tak jako tak se musí testovat oprávnění, ale člověk si pak takový formulář může zabookmarkovat, sdílet atp., pokud s ním třeba pracuje často.

Polki
Člen | 553
+
+4
-

@KamilValenta Nenene žádná sessiona.

Jde o to, že pokud má člověk na editaci vlastní stránku (například editace článku), tak musí nějak vědět, který článek chce editovat a tato informace se přenese v URL adrese například http://moje.dom/…edit/**256** kde 256 je ID článku který chci editovat. V tento moment to ID mám v url a když mám formulář jako komponentu, tak ještě před vytvořením komponenty jsem schopen v presenteru v Action metodě zjistit, jestli má ten kdo se na ten odkaz chce dostat právo tento článek editovat. No a do komponenty už pošlu to samotné ID, nebo ještě v lepším případě si entitu vytáhnu už v Presenteru, kde ověřím, jestli vůbec existuje a do formulářové komponenty pošlu rovnou už entitu z DB.
No a ta entita z db bude uložená v nějaké privátní proměnné té komponenty, aby komponenta nemusela dělat znovu dotaz na existenci entity, ale jen na případný update. A když to takto udělám, tak nemá smysl přenášet ID entity pomocí nějakého Hidden fieldu, protože ten formulář tu entitu zná od vytvoření až po konec. (Při vytvoření ji potřebuje znát aby si mohl formulářové prvky předvyplnit.)

A pokud jde třeba o editaci komentáře ke článku, kterých je na stránce třeba 15 díky multiplieru, tak tam to řeším tak, že v URL se přenáší jen a pouze ID článku, ke kterému budou ty komentáře a ověřím, jestli mám přístup k danému článku a když ano, tak z db vytáhnu všechny komentáře k danému článku (samozřejmě podle stránkování) a ve formě selectiony si je uložím zase do nějaké proměnné. No a pak když se vytváří multiplierem jednotlivé zobrazení komentářů, tak ID toho daného komentáře je ID komponenty v multiplieru, takže při odeslání se samozřejmě propíše v DO parametru do URL.
Pokud ale takto vypisuji formuláře, tak z databáze vytáhnu jen ty, které jsem schopen já editovat a zároveň pasují k tomu článku. No a pokud při odeslání formuláře ta komponenta neexistuje, respektive ID komponenty, která udělala submit neexistuje mezi těmi komentáři, tak se komponenta ani nevytvoří, takže opět toto řeším na vyšší vrstvě, ideálně v presenteru, kde se díky tomu v případě podvrhnutí jakéhokoliv ID žádná komponenta nevytvoří.

A zároveň platí jak jsi říkal, že každý formulář má svou unikátní URL, takže ho můžeš někomu poslat, nebo si URL uložit. :)

Editoval Polki (17. 5. 2022 13:42)

mimacala
Člen | 113
+
-6
-

Moc děkuji všem za názory :)
Koukám, že se tedy asi shodneme, že lepší je poslat to v hiddenu a zkontrolovat oprávnění k dané akci.
Jinak v URL bych to určitě nepředával, protože je vždy lepší to útočníkovi co nejvíce stížit a zkomplikovat, aby to neměl hned na podnose :).

Kamil Valenta
Člen | 752
+
+7
-

Spíš tu padla shoda, že je lepší to mít v URL než v hiddenu.
Oprávnění musíš kontrolovat tak jako tak, případnému útočníkovi je šumafuk, jestli je to v URL nebo v hiddenu, žádné zkomplikování se nekoná. Komplikuješ život jen běžnému uživateli, který by to naopak ocenil v URL…

Polki
Člen | 553
+
0
-

Souhlas s @KamilValenta