bei neuladen einer seite fehlermeldung anzeigen

Folgendes ist möglich (hab’ ich auch schon in verwandten Themen genannt):
PHP:
$_SESSION['token'] = md5(uniqid(rand(), true));
echo '<input type="hidden" name="token" value="'.$_SESSION['token'].'">';
PHP:
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:
$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:
$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.
 
ok, ich habe versucht das umzusetzen, bekomme jetzt aber bei klick auf "speichern" die fehlermeldung "invalid token".

hier das formularskript:agb_verwalten.php
PHP:
<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:
<?
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?
 
Du musst die Skripte etwas umstrukturieren:
PHP:
<?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:
<?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.
 
hey!

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

agb_verwalten.php
PHP:
<?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:
<?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
 
Zurück