tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
14
ZUGRIFFE
459
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    ben_19 ben_19 ist offline Mitglied Bronze
    Registriert seit
    Apr 2007
    Beiträge
    32
    hallo!

    Ich habe folgendes Script welches den Content einer Seite verwaltet. Ich benutze hierzu SPAW- einen WYSIWYG-Editor.

    Datei: agb_edit.php
    PHP-Code:
    <?
    include("agb_inc.php");
    include(
    "agb_db_inc.php");
    $abfrage "update $tabelle set text='".$_POST['text']."'";
    $result mysql_query($abfrage$conn);
    if (
    $result)
        {
            echo 
    "$erfolgreich";
        }
        else
        {
            echo 
    "$fehler";
        }
    ?>
    mit diesem script werden die eingetragenen änderungen dann in die datenbank gespeichert. mein problem: wenn man erfolgreich die änderungen eingetragen hat und die agb_edit.php neu lädt (F5 oder der Reloadbutton im Browser), dann sendet er natürlich alles noch einmal, allerdings hat er nun keine Werte mehr und schreibt einen leeren Datensatz in die Tabelle, womit der Eintrag gelöscht wird.

    Das ist natürlich kontraproduktiv. Deshalb meine Frage: Gibt es eine Möglichkeit beim Neuladen der Seite eine Fehlermeldung anzuzeigen bzw. das irgendwie zu verhindern? Ich denke da an Javascript. Hat jemand nen anderen Vorschlag bzw. kann mir jemand helfen das umzusetzen?

    Vielen Dank im Voraus
     

  2. #2
    Friesi Friesi ist offline Mitglied Gold
    Registriert seit
    Apr 2002
    Ort
    Stromberg (NRW)
    Beiträge
    175
    Wenn die Werte per $_POST übergeben werden, kannst du ja dieses machen:

    PHP-Code:
    if (!isset($_POST['foo']) {

    //normaler weiter machen
    } else {
    // doppelter Aufruf + Fehlermeldung

     

  3. #3
    Avatar von tobee
    tobee tobee ist offline Grolba.com media
    Registriert seit
    Jul 2005
    Ort
    Karlsruhe
    Beiträge
    1.700
    Blog-Einträge
    131
    Ich hatte das mal so gelöst:
    PHP-Code:
    <?
    include("agb_inc.php");
    include(
    "agb_db_inc.php");
    $abfrage "update $tabelle set text='".$_POST['text']."'";
    $result mysql_query($abfrage$conn);
    $script "<script type=\"text/javascript\">";
    if (
    $result)
        {
            
    $script .= "alert('Erfolgreich');";
        }
        else
        {
            
    $script .= "alert('Nicht Erfolgreich');";
        }
    $script .= "location.href='weiter.php'";
    $script .= "</script>";
    echo 
    $script;
    ?>
    Aber ob das so sinnvoll ist, ist ein andere Frage.
    Einfach mal probieren.
     

  4. #4
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Mein Vorschlag: Speichere im Formularskript einen bei jedem Aufruf neu generierten Zufallsschlüssel einmal in der Sitzung und einmal im Formular als verstecktes Formularelement. Im dem oben genannten Skript prüfst du dann, ob beide Schlüssel vorhanden und identisch sind. Ist dies nicht der Fall, wird das Skript abgebrochen beziehungsweise die Aktion nicht ausgeführt. Stimmen beide Schlüssel überein, wird die Aktion ausgeführt und der Schlüssel anschließend aus der Sitzung gelöscht.
     
    Markus Wulftange

  5. #5
    ben_19 ben_19 ist offline Mitglied Bronze
    Registriert seit
    Apr 2007
    Beiträge
    32
    hm, ich dachte eine javascript-meldung tuts auch ..

    aber eure vorschläge verhindern grundsätzlich das neuladen der seite was mir besser gefällt .. ist das mit den schlüsseln nicht unnötig aufwändig?

    gibts da einfachere möglichkeiten?

    @ tobee: diese idee find ich gut .. d.h. es gibt gar keine möglichkeit die seite neuzuladen weil man direkt zu einer anderen weitergeleitet wird. richtig?
     

  6. #6
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Zitat Zitat von ben_19 Beitrag anzeigen
    .. ist das mit den schlüsseln nicht unnötig aufwändig?
    Nein, dies ist sogar notwendig. Denn da jeder Schlüssel nur einmal gültig ist, werden die Formulardaten auch nur einmal verarbeitet. Die anderen genannten Vorschläge können dies nicht verhindern. Und JavaScript ist auch nicht für Aufgaben gedacht, die der Server zu erledigen hat.
     
    Markus Wulftange

  7. #7
    Avatar von tobee
    tobee tobee ist offline Grolba.com media
    Registriert seit
    Jul 2005
    Ort
    Karlsruhe
    Beiträge
    1.700
    Blog-Einträge
    131
    Zitat Zitat von ben_19 Beitrag anzeigen
    @ tobee: diese idee find ich gut .. d.h. es gibt gar keine möglichkeit die seite neuzuladen weil man direkt zu einer anderen weitergeleitet wird. richtig?
    Ja, er wartet zwar noch die JavaScript Meldung ab, aber wechselt dann direkt auf die nächste Seite. Aber dann wäre ein F5 Reload ( ein neues Query ) nicht mehr möglich.
     

  8. #8
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Zitat Zitat von tobee Beitrag anzeigen
    Ja, er wartet zwar noch die JavaScript Meldung ab, aber wechselt dann direkt auf die nächste Seite. Aber dann wäre ein F5 Reload ( ein neues Query ) nicht mehr möglich.
    Es reicht schon aus JavaScript zu deaktivieren oder einfach die vorherigen Seite aufzurufen. Ein Schutz ist das keinesfalls.
     
    Markus Wulftange

  9. #9
    ben_19 ben_19 ist offline Mitglied Bronze
    Registriert seit
    Apr 2007
    Beiträge
    32
    @ Gumbo: und der vorschlag von tobee tuts nicht auch? wie würde ich denn das umsetzen mit den automatisch generierten schlüsseln? hab sowas noch nie gemacht
     

  10. #10
    Friesi Friesi ist offline Mitglied Gold
    Registriert seit
    Apr 2002
    Ort
    Stromberg (NRW)
    Beiträge
    175
    Was spricht eigentlich gegen meine Methode?
     

  11. #11
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Folgendes ist möglich (hab’ ich auch schon in verwandten Themen genannt):
    PHP-Code:
    $_SESSION['token'] = md5(uniqid(rand(), true));
    echo 
    '<input type="hidden" name="token" value="'.$_SESSION['token'].'">'
    PHP-Code:
    if( empty($_POST['token']) || empty($_SESSION['token']) || $_POST['token'] !== $_SESSION['token'] ) {
        echo 
    'Ungültige Aktion!';
    }
    unset(
    $_SESSION['token']); 
    Dadurch ist allerdings immer nur ein Formular gültig. Wenn mehrere Formular gleichzeitig geöffnet sind, ist immer nur das zuletzt aufgerufene gültig, da der Zufallsschlüssel die vorherigen überschreibt.

    Dies kann aber dadurch verhindert werden, dass mehrere Schlüssel gespeichert werden. Dabei können auch noch weitere Werte zur Prüfung gepseichert werden, etwa:
    PHP-Code:
    $maxValidTokens 5;  // Anzahl der gleichzeitig gültigen Schlüssel
    $relPath './agb_edit.php';  // relativer Pfad zum verarbeitenden Skript
    $absPath substr(realpath($relPath), strlen($_SERVER['DOCUMENT_ROOT']));  // absoluter Pfad zum verarbeitenden Skript

    do {
        
    $token md5(uniqid(rand(), true));
    } while( isset(
    $_SESSION['tokens'][$token]) );
    $_SESSION['tokens'][$token] = array(
        
    'href' => $absPath,
        
    'time' => time(),
        
    'args' => array(
            
    'foo' => 'bar',
        ),
    );
    if( 
    count($_SESSION['tokens']) > $maxValidTokens ) {
        
    array_shift($_SESSION['tokens']);
    }

    echo 
    '<input type="hidden" name="token" value="'.$token.'">'
    PHP-Code:
    $tokenMaxLifetime 300;  // fünf Minuten Gültigkeit

    $validToken true;
    if( !isset(
    $_POST['token']) || !isset($_SESSION['tokens'][$_POST['token']]) || $_SESSION['tokens'][$_POST['token']]['href'] != $_SERVER['REQUEST_URI'] ) {
        
    $validToken false;
        echo 
    'Invalid Token';
    } else if( 
    time() - $_SESSION['tokens'][$_POST['token']]['time'] > $tokenMaxLifetime ) {
        
    $validToken false;
        echo 
    'Token expired';
    } else {
        foreach( 
    $_SESSION['tokens'][$_POST['token']] as $key => $value ) {
            
    $_POST[$key] = $value;
        }
    }
    unset(
    $_SESSION['tokens'][$_POST['token']]);
    if( 
    $validToken === true ) {
        
    // Verarbeitung der Daten

    Am besten sollten auch nicht veränderbare Argument wie etwa IDs serverseitig in der Token-Variable gespeichert werden (hier durch das „args“-Array angedeutet), damit sie für den Benutzer unsichtbar und damit auch nicht veränderbar sind.
     
    Markus Wulftange

  12. #12
    ben_19 ben_19 ist offline Mitglied Bronze
    Registriert seit
    Apr 2007
    Beiträge
    32
    danke .. ich setz das jetzt mal um .. und testen kann ich es indem ich einfach auf "zurück" oder "reload" klicke?
     

  13. #13
    ben_19 ben_19 ist offline Mitglied Bronze
    Registriert seit
    Apr 2007
    Beiträge
    32
    ok, ich habe versucht das umzusetzen, bekomme jetzt aber bei klick auf "speichern" die fehlermeldung "invalid token".

    hier das formularskript:agb_verwalten.php
    PHP-Code:
    <form action="agb_edit.php" method="post"> <!-- ändern1.php -->
    <table width="100%">
    <?
    include("agb_inc.php");
    include(
    "agb_db_inc.php");
    include(
    "spaw/spaw.inc.php");
    $abfrage "SELECT * from $tabelle";
    $result mysql_query($abfrage,$conn);
    while (
    $row mysql_fetch_array ($result))
    {
    $text $row["text"];
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ANFANG ######################
    $maxValidTokens 5;  // Anzahl der gleichzeitig gültigen Schlüssel
    $relPath 'agb_edit.php';  // relativer Pfad zum verarbeitenden Skript
    $absPath substr(realpath($relPath), strlen($_SERVER['http://www.4ahwim.com/phoenician/admin/agb_edit.php']));  // absoluter Pfad zum verarbeitenden Skript

    do {
        
    $token md5(uniqid(rand(), true));
    } while( isset(
    $_SESSION['tokens'][$token]) );
    $_SESSION['tokens'][$token] = array(
        
    'href' => $absPath,
        
    'time' => time(),
    );
    if( 
    count($_SESSION['tokens']) > $maxValidTokens ) {
        
    array_shift($_SESSION['tokens']);
    }

    echo 
    '<input type="hidden" name="token" value="'.$token.'">';  
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ENDE ######################

    ?>
    <tr>
      <td>
      <? $spaw = new SpawEditor("text"$text);
      
    $spaw->show(); ?>
      </td>
    </tr>
    <tr>
       <td><input type="submit" value="speichern"><p style="font-size:10px"><img src="important.png"> Bitte nur einmal klicken! Das System braucht einen Moment um Ihre Anfrage zu bearbeiten!</p></td>
    </tr>
    <?
    }
    ?>
    </table>
    </form>
    hier das ausführende skript: agb_edit.php
    PHP-Code:
    <?
    include("agb_inc.php");
    include(
    "agb_db_inc.php");
    $abfrage "update $tabelle set text='".$_POST['text']."'";
    $result mysql_query($abfrage$conn);
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ANFANG ######################
    $tokenMaxLifetime 300;  // fünf Minuten Gültigkeit

    $validToken true;
    if( !isset(
    $_POST['token']) || !isset($_SESSION['tokens'][$_POST['token']]) || $_SESSION['tokens'][$_POST['token']]['href'] != $_SERVER['REQUEST_URI'] ) {
        
    $validToken false;
        echo 
    'Invalid Token';
    } else if( 
    $_SESSION['tokens'][$_POST['token']]['time'] - time() > $tokenMaxLifetime ) {
        
    $validToken false;
        echo 
    'Token expired';
    } else {
        foreach( 
    $_SESSION['tokens'][$_POST['token']] as $key => $value ) {
            
    $_POST[$key] = $value;
        }
    }
    unset(
    $_SESSION['tokens'][$_POST['token']]);
    if( 
    $validToken === true ) {
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ENDE ######################
        
    if ($result)
        {
            echo 
    "$erfolgreich";
        }
        else
        {
            echo 
    "$fehler";
        }
    }
    ?>
    was mache ich falsch?
     

  14. #14
    Registriert seit
    Dec 2002
    Ort
    Trier
    Beiträge
    17.502
    Blog-Einträge
    10
    Du musst die Skripte etwas umstrukturieren:
    PHP-Code:
    <?php

        
    include("agb_inc.php"); 
        include(
    "agb_db_inc.php"); 
        include(
    "spaw/spaw.inc.php"); 

        
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ANFANG ######################

        // …

        // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ENDE ######################

    ?>
    <form action="agb_edit.php" method="post">
    <?php echo '<input type="hidden" name="token" value="'.$token.'">'?>
    <table width="100%"> 
    <?php

        $abfrage 
    "SELECT * from $tabelle";
        
    $result mysql_query($abfrage,$conn); 
        while (
    $row mysql_fetch_array ($result)) {

            
    // …

        


    ?> 
    </table> 
    </form>
    PHP-Code:
    <?php

        
    include("agb_inc.php");
        include(
    "agb_db_inc.php");

        
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ANFANG ###################### 

        // …

        // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ENDE ######################

        
    if( $validToken === true ) {
            
    $abfrage "update $tabelle set text='".$_POST['text']."'";
            
    $result = ;
            if( 
    mysql_query($abfrage$conn) ) {
                echo 
    $erfolgreich;
            } else {
                echo 
    $fehler;
            }
        }

    ?>
    Übrigens solltest du noch die eingaben filtern, damit es nicht zu SQL-Injektionen oder ähnlichem kommen kann.
     
    Markus Wulftange

  15. #15
    ben_19 ben_19 ist offline Mitglied Bronze
    Registriert seit
    Apr 2007
    Beiträge
    32
    hey!

    danke für die hilfe, aber leider habe ich immer noch die fehlermeldung "invalid token".

    agb_verwalten.php
    PHP-Code:
    <?php

        
    include("agb_inc.php"); 
        include(
    "agb_db_inc.php"); 
        include(
    "spaw/spaw.inc.php"); 

        
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ANFANG ######################

        
    $maxValidTokens 5;  // Anzahl der gleichzeitig gültigen Schlüssel
    $relPath 'agb_edit.php';  // relativer Pfad zum verarbeitenden Skript
    $absPath substr(realpath($relPath), strlen($_SERVER['http://www.4ahwim.com/phoenician/admin/agb_edit.php']));  // absoluter Pfad zum verarbeitenden Skript

    do {
        
    $token md5(uniqid(rand(), true));
    } while( isset(
    $_SESSION['tokens'][$token]) );
    $_SESSION['tokens'][$token] = array(
        
    'href' => $absPath,
        
    'time' => time(),
    );
    if( 
    count($_SESSION['tokens']) > $maxValidTokens ) {
        
    array_shift($_SESSION['tokens']);
    }

    echo 
    '<input type="hidden" name="token" value="'.$token.'">';   

        
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ENDE ######################

    ?>
    <form action="agb_edit.php" method="post">
    <?php echo '<input type="hidden" name="token" value="'.$token.'">'?>
    <table width="100%"> 
    <?php

        $abfrage 
    "SELECT * from $tabelle";
        
    $result mysql_query($abfrage,$conn); 
        while (
    $row mysql_fetch_array ($result)) {

            
    $text $row["text"];
    ?>
            <tr>
      <td>
      <? $spaw = new SpawEditor("text"$text);
      
    $spaw->show(); ?>
      </td>
    </tr>
    <tr>
       <td><input type="submit" value="speichern"><p style="font-size:10px"><img src="important.png"> Bitte nur einmal klicken! Das System braucht einen Moment um Ihre Anfrage zu bearbeiten!</p></td>
    </tr>
    <?
    }
    ?>
    </table> 
    </form>
    agb_edit.php
    PHP-Code:
    <?php

        
    include("agb_inc.php");
        include(
    "agb_db_inc.php");

        
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ANFANG ###################### 

        
    $tokenMaxLifetime 300;  // fünf Minuten Gültigkeit

    $validToken true;
    if( !isset(
    $_POST['token']) || !isset($_SESSION['tokens'][$_POST['token']]) || $_SESSION['tokens'][$_POST['token']]['href'] != $_SERVER['REQUEST_URI'] ) {
        
    $validToken false;
        echo 
    'Invalid Token';
    } else if( 
    $_SESSION['tokens'][$_POST['token']]['time'] - time() > $tokenMaxLifetime ) {
        
    $validToken false;
        echo 
    'Token expired';
    } else {
        foreach( 
    $_SESSION['tokens'][$_POST['token']] as $key => $value ) {
            
    $_POST[$key] = $value;
        }
    }
    unset(
    $_SESSION['tokens'][$_POST['token']]);
    if( 
    $validToken === true ) { 

        
    // #################### AUTOMATISCH GENERIERTER ZUFALLSSCHLÜSSEL ENDE ######################

        
    if( $validToken === true ) {
            
    $abfrage "update $tabelle set text='".$_POST['text']."'";
            
    $result mysql_query($abfrage$conn);
            if( 
    mysql_query($abfrage$conn) ) {
                echo 
    $erfolgreich;
            } else {
                echo 
    $fehler;
            }
        }
    }

    ?>
    wo liegt der fehler?

    achja und das mit den injections werde ich noch machen
     

Ähnliche Themen

  1. Nur ein Teil einer Seite neuladen
    Von Duellking im Forum Javascript & Ajax
    Antworten: 5
    Letzter Beitrag: 17.04.09, 08:00
  2. Antworten: 5
    Letzter Beitrag: 18.07.08, 13:43
  3. Pobleme beim Neuladen einer Seite
    Von mkoeni1 im Forum Javascript & Ajax
    Antworten: 1
    Letzter Beitrag: 19.11.07, 12:38
  4. Antworten: 1
    Letzter Beitrag: 05.01.07, 09:19
  5. Antworten: 3
    Letzter Beitrag: 22.06.04, 09:34