"zurück" verhindern
-
Hi,
wie kann man es "verhindern" das jemand mittels des "zurück" Buttons von Browser, Maus etc. sich eine Seite noch einmal ansieht bzw. wie kann man sie dann disablen/"ungültig" machen?
Grund: es wird auf der Seite der Inhalt eines Formulares in eine Datenbank geschrieben, nun soll der Besuch aber nicht mit dem oben genannten "zurück" Button die Seite nochmal aufrufen und den inhalt in die DB schreiben können.
Gruß,
Heimwerkerking
-
Und wie willst du verhindern, dass er die Adresse kopiert und einfach nochmals aufruft? Ich glaub dein Ansatz wird so nichts.
Besser: Jedes Formular bekommt eine ID, wenn der nun ein Formular gesendet hat speicherst du es in der Session des Users bzw. in einer DB und weißt dann "Aha der darf nicht mehr senden".
MfG SideWinder
-
hmmmm, hab ich wahrscheinlich wieder dumm beschrieben...
Das ganze soll in etwa so laufen wie wenn ich hier im Forum einen Beitrag geschrieben habe und dann "Back" im Browser anklicke. Dann zeigt mir doch auch sowas an wie blablabla ist ungültig oder so ähnlich.
Ob er jetzt den Link einfach nimmt und in seine Adressleiste wieder einträgt ist egal - es soll nur dieses "zurück" verhindert werden.
Gruß,
Christian
-
Hallo!
Das klassische Problem, dass ein Browser POST-Daten erneut sendet, kann (soweit ich weiß) nur dann auftreten, wenn der Benutzer ein Formular abschickt und auf der Zielseite anschließend auf den Zurück-Button klickt (oder auch wenn er auf den Submit-Button mehrmals klickt). Im speziellen Fall, wo das Zielscript das Script selbst ist, welches das Formular in erster Linie generiert hat, braucht man nur die Seite aktualisieren um die POST-Daten nochmal zu senden. Der Browser dürfte keine (alten) Formulardaten versenden, wenn ich den Link in einem neuen Fenster einfügen würde. Soviel mal dazu :p
Um dieses Problem sicher zu beseitigen, hat Sidewinder ja bereits eine gängige Lösung vorgeschlagen. Ich beschreibe dir mal genau was du zu tun hast:
1.) Im Skript, wo das Formular generiert wird, musst du eine einzigartige ID generieren (auch als Ticket bekannt), die du in einem Hidden Field dem Formular anhängst. Zusätzlich musst du diese ID als Variable im Session-Array speichern. Ein bisschen Beispielcode mit einer Funktion von mir:
//generate_form.php function genTicket($opname) { if( !isset($_SESSION['tickets']) ) $_SESSION['tickets'] = array(); //microtime(true) geht nur mit PHP5 //Alternativ: //list($sec, $usec) = explode(' ', microtime()); //mt_srand((float) $sec + ((float) $usec * 100000)); //$ticket = md5(uniqid(mt_rand(), true)); mt_srand(microtime(true)*100000); return $_SESSION['tickets'][$opname] = md5(uniqid(mt_rand(), true)); } //resume Session //...arbitrary code... $ticket = genTicket('new_posting'); echo <<<FORM <form action="process_form.php" method="post"> <p> <label>Title:</label> <input name="title" value="" /> <label>Message Body:</label> <input name="body" value="" /> <input type="submit" name="submit_post" value="Submit" /> <input type="hidden" name="ticket" value="$ticket" /> </p> </form> FORM;
2.) Wenn der Benutzer seine Daten in die Formularfelder eingetragen und sie daraufhin abgeschickt hat, muss im Zielscript folgendes passieren: bevor die POST-Daten weiter verarbeitet werden, muss überprüft werden ob das Ticket im POST-Array mit dem Ticket im Session-Array übereinstimmt. In der Regel wird es das auch, außer die Session ist während der Eingabe des Users bereits abgelaufen (dafür kann man aber Lösungen finden). Wichtig ist, dass das Ticket aus dem Session-Array gelöscht wird, denn wenn der User nun den Zurück-Button betätigt sendet der Browser die alten POST-Daten mit dem alten Ticket, aber das Zielscript lehnt diese ab, da kein aktuelles/gültiges Ticket vorhanden ist. Das ist der ganze Sinn dieser Tickets. So könnte dein Zielskript aussehen:
//process_form.php function consumeTicket($opname, $ticket) { if( /*!isset($_SESSION['tickets']) ||*/ !isset($_SESSION['tickets'][$opname]) ) return false; if( $_SESSION['tickets'][$opname] === $ticket ){ return true; } unset($_SESSION['tickets'][$opname]); return false; } //resume Session if( !consumeTicket('new_posting', $_POST['ticket']) ) die('Your ticket has either expired, was already consumed or is invalid.'); //continue processing post data
Die Funktionen kann jeder frei verwenden ohne meinen Namen od. ein Copyright zu erwähnen. Ich würde mich allerdings freuen, eure Ideen/Verbesserungsvorschläge/Kritik diesbezüglich zu hören.
-
wenn ich hier im Forum einen Beitrag geschrieben habe und dann "Back" im Browser anklicke. Dann zeigt mir doch auch sowas an wie blablabla ist ungültig oder so ähnlich.
Das ist ein kleines Extra, schützt dich aber noch lange nicht vor Mehrfachposting. Er kann dir die Daten nämlich auch per Prorgamm 100 Mal senden - ohne eine Lösung wie oben beschrieben hast du keine Chance das zu verhindern.
MfG SideWinder
-
*Doppelpost*
BTW: Ich bekomm hier beim Klicken auf Zurück keine Fehlermeldnug oder Sonstiges angezeigt...
MfG SideWinder
-
SideWinder schrieb:
BTW: Ich bekomm hier beim Klicken auf Zurück keine Fehlermeldnug oder Sonstiges angezeigt...
Ist ne Eigenart des grottigen IEs. Wirst den wohl nicht verwenden
Bei anderen Browsern (kann hier mit Sicherheit nur von Opera sprechen) erübrigt sich sowas sowieso, da die keine Daten - auch wenn man "zurück" klickt - doppelt senden (Schließlich heißt der Button ja auch "Zurück" und nicht "mach noch einmal" ...)
-
Hmmmm...
Okay werd ich das so machen, danke für die Hilfe.Gruß,
Heimwerkerking
-
Es gibt noch eine alternative Methode um dieses Problem zu lösen: Redirect After Post
Ich hab den Artikel nur überflogen, aber es scheint eine interessante Methode zu sein das nochmalige Senden von POST-Daten zu unterdrücken. Die Technik mit Tickets kann man allerdings trotzdem verwenden um Operationen in sensiblen Bereichen (Admin Panel) zu sichern.