Защита от повторной отправки формы в php

21 Май
2012

Вполне очевидно, что при отправке формы нужно защищаться от повторной отправки. Чаще всего повторная отправка может произойти в случае, когда пользователь нажимает F5 «перезагрузить страницу».

Ниже приведенный способ я использую в своих системах администрирования и он очень простой.

Так как речь идет о системе администрирования, то у нас есть таблица пользователей. Создаем в ней поле sign, varchar(32). В этом поле будем хранить произвольный хешь, назовем ее условно подписью запроса.

При успешном заходе пользователя устанавливаем ее для текущей сессии пользователя


$sign=md5(date("YmdHisu").rand(1,9999));
$sql="update users set sign='$sign' where id='$id'";
$res = mysql_query($sql);


Обычно данные текущего пользователя я храню в массиве для использования.
$sql = "select * from users where id='$id' and status=1 LIMIT 1";
$res = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($res) == 1) {
$logged_in_user = mysql_fetch_assoc($res);
}

Запрос само собой выполняется после проверки подлинности пользователя и мы получили $id.

Далее в любой форме делаем дополнительный параметр sign


input type="hidden" name="sign" value="<?=$logged_in_user[sign];?>"


И в обработчике формы:


$sign=$_REQUEST[sign];
if ($sign and $sign==$logged_in_user[sign]) {
// подпись правильная
.......
recreate_sign();
} else {
// подпись неправильная
.....
}


Функция recreate_sign()


function recreate_sign() {
global $logged_in_user;
$newsign=md5(date("YmdHisu").rand(1,100));
$sql1="update users set sign='$newsign' where id='$logged_in_user[id]' limit 1";
$res1 = mysql_query($sql1);
$logged_in_user[sign]=$newsign;
}


Что получилось


Таким образом при повторной отсылке формы текущая подпись в таблице users и соответственно в массиве $logged_in_user не будет совпадать с подписью в $_REQUEST — отсылаем мы ведь все теже данные.

Способ очень простой, но помогает избавиться от мусорных данных, которые пользователи заносят через Refresh/F5. Для незалогиненного пользователя тоже можно применить храня подпись не в таблице users, а всего лишь в cookie.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх