【问题标题】:Why can't I trust a client-generated GUID? Does treating the PK as a composite of client-GUID and a server-GUID solve anything?为什么我不能信任客户端生成的 GUID?将 PK 视为客户端 GUID 和服务器 GUID 的组合是否可以解决任何问题?
【发布时间】:2013-03-31 04:59:43
【问题描述】:

我正在构建 a previous discussion I had with Jon Skeet

我的方案的要点如下:

  • 客户端应用程序能够创建新的“PlaylistItem”对象,这些对象需要保存在数据库中。
  • 用例要求创建 PlaylistItem,这样客户端在显示 PlaylistItem 之前不必等待来自服务器的响应。
  • 客户端为 PlaylistItem 生成 UUID,在客户端显示 PlaylistItem,然后向服务器发出保存命令。

此时,我了解到在我的数据库中使用客户端生成的 UUID 作为对象的 PK 是一种不好的做法。原因是恶意用户可以修改生成的 UUID 并在我的数据库上强制 PK 冲突。

为了减轻因在 PlaylistItem 上强制 PK 冲突而造成的任何损害,我选择将 PK 定义为两个 ID 的组合 - 客户端生成的 UUID 和服务器生成的 GUID。服务器生成的 GUID 是 PlaylistItem 的播放列表的 ID。

现在,我已经使用此解决方案一段时间了,但我不明白为什么/相信我的解决方案比简单地信任客户端 ID 更好。如果用户能够强制与另一个用户的 PlaylistItem 对象发生 PK 冲突,那么我认为我应该假设他们也可以提供该用户的 PlaylistId。他们仍然可以强制碰撞。

所以...是的。做这样的事情的正确方法是什么?允许客户端创建 UUID,成功保存时服务器会竖起大拇指。如果发现冲突,恢复客户端更改并通知检测到冲突?

【问题讨论】:

    标签: client-server primary-key client-side guid composite-key


    【解决方案1】:

    可以信任客户端生成的 UUID 或服务器上类似的全局唯一标识符。明智地去做。

    您的大多数表/集合还将保存一个 userId 或能够通过 FK 将自己与 userId 关联。

    如果您正在执行插入并且恶意用户使用现有密钥,则插入将失败,因为记录/文档已经存在。

    如果您正在进行更新,那么您应该验证登录用户是否拥有该记录或被授权(例如管理员用户)更新它。如果强制执行纯所有权(即没有管理员用户场景),那么您在定位记录/文档时的 where 子句将包括 Id 和 userId。现在从技术上讲,userId 在 where 子句中是多余的,因为 Id 将唯一地找到一个记录/文档。但是,添加 userId 可以确保记录属于进行更新的用户,而不是恶意用户。

    我假设服务器正在解密某种加密令牌或会话以确定 userId,并且这不是由客户端提供的,否则显然不安全。

    【讨论】:

    • 在我了解到我使用的文档数据库 (CosmosDB) 不强制使用唯一 ID 之前,我也有同样的看法。 IE。它的“id”字段仅在逻辑分区中是唯一的。就我而言,使用客户端生成的 UUID 是危险的。
    【解决方案2】:

    一个不错的解决方案如下:引用 Sam Newman 的 "Building Microservices"

    调用系统会发布一个 BatchRequest,可能会传入一个 可以将文件与所有数据一起放置的位置。客户 服务将返回 HTTP 202 响应代码,表明 请求已被接受,但尚未处理。呼唤 然后系统可以轮询资源,等待它检索到 201 创建表示请求已完成

    因此,在您的情况下,您可以 POST 到服务器,但会立即收到类似“我将保存 PlaylistItem 并且我保证它的 Id 将是这个”的响应。然后,客户端(和用户)可以继续,而服务器(甚至可能不是 API,而是一些从 API 获取消息的后台处理器)花时间处理、验证和执行其他可能很繁重的逻辑,直到它保存实体。如前所述,API 可以为该请求的状态提供一个 GET 端点,客户端可以轮询它并在出现错误时采取相应的行动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      • 2012-11-30
      • 1970-01-01
      相关资源
      最近更新 更多