Предотвращение состояния гонки в конечной точке - PullRequest
0 голосов
/ 22 июня 2019

Я даю пользователю конечную точку для вывода своего баланса.

Так что внутри моего http-сервиса я делаю что-то вроде:

var balance = currentBalance - withdrawlAmount;
ProcessWithdrawl(withdrawlAmount);
SaveBalance(balance);

Это не мой настоящий код, простоПридуманный пример, чтобы объяснить себя.

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

Какой самый простой способ защититься от этого?Одна идея заключается в том, что я использую статический объект и код переноса в операторе lock().Это позволило бы обновлять только один баланс пользователя за один раз.

Как вы устанавливаете блокировку для сеанса аутентификации пользователей?Есть ли простой способ сделать это?

1 Ответ

0 голосов
/ 22 июня 2019

Как обсуждалось в комментариях, поскольку вам необходим общий объект для всех пользовательских сессий, я бы порекомендовал shared / static data structure на стороне сервера, который может предоставить уникальный объект для каждого пользователя.

Случай 1: один сервер (без веб-сада) - не кластер или веб-ферма

  1. Создать структуру данных, static ConcurrentDictionary<UserId,Object>, здесь UserId - уникальный для пользователя уникальный идентификатор, string, int, guid
  2. Используйте объект Value для блокировки согласно сценарию использования, и он создаст специфическую для пользователя блокировку / критическую область для выполнения операции
  3. lock(ConcurrentDictionary[UserId]) { ... }
  4. ConcurrentDictionary для обработки параллелизма на стороне сервера
  5. блокировка - не единственная опция, вы даже можете запланировать дескриптор ожидания события для конкретного пользователя, чтобы сигнализировать об ожидании и отпускании для конкретного пользователя

Случай 2: Кластер или веб-сад / ферма

  1. Нам необходимо сместить доступ к общему ресурсу к распределенной структуре данных, такой как Cache, MQ, Database, которая может синхронизировать пользовательские запросы, и все пользователи получают доступ к одному и тому же распределенному ресурсу
  2. Здесь доступно множество вариантов, которые зависят от конструкции системы и вариантов использования
...