Как обрабатывать несколько представлений на стороне сервера
Мы все знаем старый добрый трюк "отключить кнопку отправки", но как лучше всего обрабатывать несколько запросов на стороне сервера? У меня есть приложение, в котором абсолютно важно, чтобы форма отправлялась только один раз - она обрабатывает кредитную карту. Я не писал, как это сейчас, но в качестве быстрого исправления я добавил технику "отключить при отправке", однако некоторые нетерпеливые пользователи, у которых отключен JavaScript, по-прежнему взимают плату дважды.
Итак, как можно этого избежать? Я могу вспомнить некоторые из них - я использовал несколько в прошлом - но я хотел бы посмотреть, есть ли "лучшие практики" в отношении того, как справиться с этим. Я использую PHP, но меня больше интересуют концепции.
редактировать: я знаю о методе токенов, и это то, что я использовал в прошлом, этот вопрос более или менее, чтобы увидеть, соответствует ли мой подход тому, что используют остальные из вас прекрасные программисты.
6 ответов
Один действительно эффективный способ - отправить токен вместе с запросом и сохранить список используемых токенов. Если токен недействителен или токен уже обработан, прервать его.
Токен может быть простым целым числом, хранящимся в скрытом текстовом поле, или вы можете зашифровать его для повышения безопасности. Эту функцию можно сделать более надежной, создав токен при создании страницы, зашифровав его и подтвердив, что токен сгенерирован и не обработан.
Включите случайный уникальный токен в скрытое поле формы. Затем на бэкэнде вы можете проверить, был ли он представлен ранее.
Обычно это хорошая идея, потому что она помогает вам защищаться и от XSS-атак.
Вы также можете просто проверить, была ли сделана идентичная транзакция за последнюю минуту (или секунду, в зависимости от задержки вашего сервера). Большинство людей не покупают две одинаковые книги (или что-то еще) в течение минуты друг от друга, используя одну и ту же карту. Если вы сохраняете кэш платежей по кредитным картам в последнюю минуту и проверяете, идентичен ли тот, который вы собираетесь сделать (тот же номер карты, та же сумма) тому, который вы только что сделали, скорее всего, вы обнаружите дубликат,
Я бы не стал полагаться ни на что со стороны клиента. Почему бы не сгенерировать уникальный идентификатор для этой транзакции на стороне сервера, прежде чем предоставить клиенту кнопку отправки? Затем клиент должен отправить этот токен обратно, и вы проверяете на стороне сервера, что каждый токен передается один раз.
Токен, как говорили другие люди, может быть целым числом (+ имя пользователя) или GUID.
У меня похожая проблема. Прочитав это, я думаю, что токен может быть подходящим способом. Этот пост показывает хороший пример реализации.
Не нужно генерировать уникальные токены и все такое прочее. После того, как проверка формы пройдет успешно, просто перенаправьте посетителя на другую страницу, которая говорит что-то вроде "Ваша кредитная карта обрабатывается". Если посетитель перезагружает страницу, он перезагружает перенаправленную страницу, а не отправку POST.