<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Refresh woes</title>
</head>
<body>
<?PHP
if ($_GET['submit'] == 1) {
echo 'Sending money - lets hope the client does not refresh and accidentially sends money twice!';
} else {
?>
<form action="<?= $_SERVER['PHP_SELF'] ?>?submit=1" method="post">
<input type="submit" value="Send Money" />
</form>
<?PHP
}
?>
</body>
</html>
/* createtoken()
* Function to create a new token
* Returns the new token
*/
function createtoken() {
/* First we need to check if a session token exists already */
if (!count($_SESSION['token'])) {
/* There is no previous session token for this client, so we need to create a new token */
$txid = rand(1, 99999);
/* Here we specify the amount of uses this token should have. 1 is recommended */
$_SESSION['token']['_' . $txid] = 1;
}
/* Next we check if the current token is out of uses */
if (current($_SESSION['token']) == 0) {
/* We preserve the old token to make sure it does not randomly roll the same number again */
$oldtx = key($_SESSION['token']);
unset($_SESSION['token']);
/* This loop prevents the same transaction ID from re-appearing. */
do {
$txid = rand(1, 99999);
} while ('_' . $txid == $oldtx);
$_SESSION['token']['_' . $txid] = 1;
}
/* And finally, we return the new transaction ID */
return $curtx = key($_SESSION['token']);
}
<?PHP
/* We have to start the session in order to use the session functionality */
session_start();
/* createtoken()
* Function to create a new token
* Returns the new token
*/
function createtoken() {
/* First we need to check if a session token exists already */
if (!count($_SESSION['token'])) {
/* There is no previous session token for this client, so we need to create a new token */
$txid = rand(1, 99999);
/* Here we specify the amount of uses this token should have. 1 is recommended */
$_SESSION['token']['_' . $txid] = 1;
}
/* Next we check if the current token is out of uses */
if (current($_SESSION['token']) == 0) {
/* We preserve the old token to make sure it does not randomly roll the same number again */
$oldtx = key($_SESSION['token']);
unset($_SESSION['token']);
/* This loop prevents the same transaction ID from re-appearing. */
do {
$txid = rand(1, 99999);
} while ('_' . $txid == $oldtx);
$_SESSION['token']['_' . $txid] = 1;
}
/* And finally, we return the new transaction ID */
return $curtx = key($_SESSION['token']);
}
/* start the token system */
$curtx = createtoken();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Refresh woes</title>
</head>
<body>
<?PHP
if ($_GET['submit'] == 1) {
/* This information needs to be added to the part of the page that you DON'T want to execute twice
* First we need to test if we currently have a valid token, and if we do not, we output a error. */
if ((!isset($_SESSION['token'][$_POST['tx']]) || $_SESSION['token'][$_POST['tx']] <= 0)) {
echo '<p>Prevented page reload from re-sending money.</p>';
} else {
/* Removing one token use */
$_SESSION['token'][$_POST['tx']]--;
echo '<p>Sending money - now refresh-protected!</p>';
}
} else {
?>
<form action="<?= $_SERVER['PHP_SELF'] ?>?submit=1" method="post">
<!-- We need to pass along the current transaction ID -->
<input type="hidden" name="tx" value="<?= $curtx ?>"/>
<input type="submit" value="Send Money" />
</form>
<?PHP
}
?>
</body>
</html>
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (0)