Простой способ - использовать javascript для отключения кнопки, когда пользователь нажимает на нее.
Способ, который я использую, чтобы избежать обновления, когда требуется высокий уровень безопасности, - это использование небольшого «токена» в сеансе.
Допустим, мы поместили небольшое 32-битное целое число в нашу сессию.
Страница будет содержать скрытый ввод, содержащий наш маленький целочисленный токен.
Каждый раз, когда мы получаем запрос страницы, мы увеличиваем этот токен на единицу и, прежде чем сделать это, мы проверяем на равенство с тем, который получен в запросе.
Если они совпадают, это не обновление.
Если они не совпадают, это обновление.
Это также блокирует попытки сделать назад и далее с помощью кнопок браузера.
Конечно, в тот момент, когда токен не совпадает, страница должна измениться, иначе у вас снова возникнет проблема обновления.
Должно отображаться что-то вроде «эй, обновление назад или следующее не разрешено, нажмите здесь, чтобы продолжить».
Для повышения безопасности вы можете xor это целое число со значением costant, зависящим, например, от некоторого другого значения, которое является постоянным в сеансе.