Почему я не могу доверять GUID, созданному клиентом? Решает ли что-нибудь обработка ПК как смеси GUID клиента и GUID сервера?

Я строю на основе предыдущее обсуждение, которое я провел с Джоном Скитом.

Суть моего сценария такова:

  • Клиентское приложение имеет возможность создавать новые объекты PlaylistItem, которые необходимо сохранить в базе данных.
  • Вариант использования требует, чтобы PlaylistItem был создан таким образом, чтобы клиенту не приходилось ждать ответа от сервера перед отображением PlaylistItem.
  • Клиент генерирует UUID для PlaylistItem, показывает PlaylistItem в клиенте, а затем выдает команду сохранения на сервер.

На данный момент я понимаю, что было бы плохой практикой использовать UUID, сгенерированный клиентом, в качестве PK объекта в моей базе данных. Причина этого в том, что злоумышленник может изменить сгенерированный UUID и вызвать конфликты PK в моей БД.

Чтобы уменьшить любые убытки, которые могут возникнуть в результате принудительного столкновения PK в PlaylistItem, я решил определить PK как составную часть двух идентификаторов - UUID, созданного клиентом, и GUID, созданного сервером. Созданный сервером GUID - это идентификатор списка воспроизведения PlaylistItem.

Я использую это решение некоторое время, но я не понимаю, почему / считаю, что мое решение лучше, чем просто доверять идентификатору клиента. Если пользователь может вызвать столкновение PK с объектами PlaylistItem другого пользователя, я думаю, я должен предположить, что они также могут предоставить PlaylistId этого пользователя. Они все еще могли вызывать столкновения.

Так что да. Как правильно делать что-то подобное? Разрешить клиенту создать UUID, сервер показывает палец вверх / вниз при успешном сохранении. Если обнаружена коллизия, отменить изменения клиента и уведомить об обнаруженной коллизии?


person Sean Anderson    schedule 08.04.2013    source источник


Ответы (2)


Хорошим решением было бы следующее: Процитируем "Здание Сэма Ньюмана" Микросервисы »:

Вызывающая система будет POST a BatchRequest, возможно, передав место, где можно разместить файл со всеми данными. Служба поддержки клиентов вернет код ответа HTTP 202, указывающий, что запрос был принят, но еще не обработан. Затем вызывающая система может опросить ресурс, ожидая, пока он не получит 201 Created, указывающее, что запрос был выполнен.

Итак, в вашем случае вы можете выполнить POST на сервер, но сразу получите ответ вроде «Я сохраню PlaylistItem и обещаю, что его идентификатор будет таким». Затем клиент (и пользователь) может продолжить, пока сервер (возможно, даже не API, а какой-то фоновый процессор, получивший сообщение от API) не торопится обрабатывать, проверять и выполнять другую, возможно, сложную логику, пока не сохранит сущность. Как указывалось ранее, API может предоставить конечную точку GET для определения статуса этого запроса, и клиент может опросить его и действовать соответствующим образом в случае ошибки.

person zafeiris.m    schedule 27.02.2015

Вы можете доверять созданному клиентом UUID или подобному глобальному уникальному идентификатору на сервере. Просто делайте это разумно.

Большинство ваших таблиц / коллекций также будут содержать userId или иметь возможность связывать себя с userId через FK.

Если вы выполняете вставку, а злоумышленник использует существующий ключ, вставка не удастся, потому что запись / документ уже существует.

Если вы выполняете обновление, вы должны подтвердить, что зарегистрированный пользователь владеет этой записью или имеет право (например, пользователь с правами администратора) на ее обновление. Если применяется чистое владение (т.е. нет сценария пользователя-администратора), то ваше предложение where при поиске записи / документа будет включать как идентификатор, так и идентификатор пользователя. Теперь технически userId является избыточным в предложении where, потому что Id однозначно найдет одну запись / документ. Однако добавление userId гарантирует, что запись принадлежит пользователю, выполняющему обновление, а не злоумышленнику.

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

person Guy    schedule 28.08.2016
comment
У меня было такое же мнение, пока я не узнал, что база данных документов, которую я использовал (CosmosDB), НЕ обеспечивает уникальные идентификаторы. Т.е. Это поле id уникально только в пределах логического раздела. В моем случае использование UUID, созданного клиентом, опасно. - person Peter L; 25.07.2019