我在之前与Jon Skeet讨论的基础上构建。
我的方案大意如下:
客户端应用程序可以创建新的“PlaylistItem”对象,并将其持久化到数据库中。
使用情况要求以这种方式创建PlaylistItem,以便客户端在显示PlaylistItem之前无需等待服务器响应。
客户端生成一个UUID用于PlaylistItem,在客户端显示该PlaylistItem,然后向服务器发出保存命令。
现在,我明白在我的数据库中使用客户端生成的UUID作为对象的主键是不好的做法。原因是恶意用户可以修改生成的UUID,强制PK在我的数据库中发生冲突。
为了减轻由于强制PK冲突而造成的任何损失,我选择将PK定义为两个ID的组合 - 客户端生成的UUID和服务器生成的GUID。服务器生成的GUID是PlaylistItem的Playlist的ID。
现在,我已经使用这个解决方案有一段时间了,但我不明白为什么/相信我的解决方案比简单地信任客户端ID更好。如果用户能够强制使PK与另一个用户的PlaylistItem对象发生碰撞,那么我认为他们也可以提供该用户的PlaylistId。他们仍然可以强制碰撞。
我的方案大意如下:
客户端应用程序可以创建新的“PlaylistItem”对象,并将其持久化到数据库中。
使用情况要求以这种方式创建PlaylistItem,以便客户端在显示PlaylistItem之前无需等待服务器响应。
客户端生成一个UUID用于PlaylistItem,在客户端显示该PlaylistItem,然后向服务器发出保存命令。
现在,我明白在我的数据库中使用客户端生成的UUID作为对象的主键是不好的做法。原因是恶意用户可以修改生成的UUID,强制PK在我的数据库中发生冲突。
为了减轻由于强制PK冲突而造成的任何损失,我选择将PK定义为两个ID的组合 - 客户端生成的UUID和服务器生成的GUID。服务器生成的GUID是PlaylistItem的Playlist的ID。
现在,我已经使用这个解决方案有一段时间了,但我不明白为什么/相信我的解决方案比简单地信任客户端ID更好。如果用户能够强制使PK与另一个用户的PlaylistItem对象发生碰撞,那么我认为他们也可以提供该用户的PlaylistId。他们仍然可以强制碰撞。
所以...是的。像这样做的正确方式是什么?允许客户端创建UUID,服务器在成功保存时给出肯定/否定。如果发现碰撞,则恢复客户端更改并通知检测到碰撞?