Сессия записывается недостаточно быстро, чтобы предотвратить дублирование представления форм на сервере. (Laravel) - PullRequest
0 голосов
/ 31 октября 2019

У меня есть запрос createOrder, который в настоящее время немного медленный (около 3 - 4 секунд). Я пытаюсь предотвратить повторную отправку формы с помощью токена CSRF или пользовательского токена.

Для этого случая я использую камердинер с драйвером файла ... так что это может быть проблемой, но я пока не помещаю этот код на производственный сервер, поскольку он не работает, как предполагалось.

Работает так:

  • Токен добавляется в сеанс и в форму отправки в скрытом "custom_token" поле.

  • Форма отправлена, и либо в промежуточном программном обеспечении, либо в самом контроллере мы проводим быстрое сравнение.

if(! hash_equals($request->session()->get('custom_token'), $request->custom_token)){
    flash()->error('Order placed twice');
    return redirect('/checkout/thank-you');
}

$request->session()->put('custom_token', Str::random(40));
  • Если они не совпадают, мы делаем быстрый редирект(Flash-сообщение доступно только для отладки в настоящее время).

Вышеприведенное работает, если я удаляю основной вызов create orde из контроллера (т. Е. Медленный бит), но с учетом этого hash_equals всегда возвращает true.

Итак, мои вопросы:

  1. Это может быть вызвано медленным обновлением драйвера файла сеанса?
  2. Конечно, если это так, даже впроизводственная среда все еще есть некоторый риск этогопроисходит.
  3. Есть ли лучший способ предотвратить повторную отправку формы на сервер?

Ответы [ 3 ]

1 голос
/ 31 октября 2019

Несколько вещей, во-первых, я бы выяснил, почему ваш createOrder занимает так много времени, от 3 до 4 секунд. Используйте очередь (https://laravel.com/docs/5.8/queues) и обработайте большую часть работы там.

Ваше решение должно работать нормально, если его поместить в начало контроллера. Возможно, я толстый, но вы хотитеотвергать те, где хэш совпадает, поэтому вам нужно удалить!

т.е.

if(hash_equals($request->session()->get('custom_token'), $request->custom_token)){
    flash()->error('Order placed twice');
    return redirect('/checkout/thank-you');
}

$request->session()->put('custom_token', Str::random(40));

Я предполагаю, что вы создаете свой хэш, сохраняете его и передаете его вам в форму, и онаправильно вернул ваш контроллер в запросе $? Попробуйте установить custom_token что-то вроде 'fred_bloggs' и просто убедитесь, что он входит правильно.

0 голосов
/ 31 октября 2019

Попробуйте использовать транзакцию с попыткой перехвата в коде контроллера:

try{
   \DB::beginTransaction(); //initiate the transaction and lock the database or table
   //execute your desired code here

   \DB::commit(); //commit the changes and unlock the database or table
}catch(\Exception $e){
   \DB::rollback(); //revert to original state if something goes wrong
}
0 голосов
/ 31 октября 2019

Почему бы просто не отключить кнопку отправки после отправки формы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...