客户端生成的 UUID 是否可用于插入 Postgres?

4
创建数据库项的通常做法是让数据库控制主键(id)的生成。无论您使用自增整数id还是UUID,这通常都是正确的。
我正在构建一个客户端应用程序(Angular,但技术并不重要),希望能够将离线行为集成到其中。为了允许离线对象的创建和关联,我需要客户端应用程序为新对象生成主键。这既是为了允许与离线创建的其他对象进行关联,也是为了保证幂等性(确保由于网络问题而不小心将相同的对象保存两次)。
然而,挑战在于当该对象发送到服务器时会发生什么。您是使用临时的客户端ID,然后用服务器随后生成的ID替换它,还是在客户端和服务器之间使用某种ID翻译层- 这就是Trello在构建其离线功能时所做的
然而,我想到可能有第三种方法。我在后端为所有表使用UUID。因此,这使我意识到我可以理论上将在前端生成的UUID插入到后端中。 UUID的整个目的是它们是通用唯一标识符,因此前端不需要知道服务器状态来生成一个。如果它们碰撞的可能性很小,则服务器上的唯一性标准会防止重复。

这是一种合法的方法吗?风险似乎是1.碰撞和2.我没有预料到的任何形式的安全性。 UUID的生成方式似乎已经解决了碰撞问题,但我无法确定允许客户端选择插入对象的ID是否存在风险。


2
本质上并没有安全风险。这取决于您的应用程序和API允许什么,是否有攻击者可以通过能够指定他们本来不会的ID来执行某些操作... - deceze
1个回答

3
然而,我想到可能有第三种方法。我在后端为所有表使用UUID。这使我意识到,理论上,我可以将在前端生成的UUID插入到后端中。UUID的整个目的在于它们是通用唯一标识符,因此前端不需要知道服务器状态即可生成一个UUID。如果它们碰撞的可能性很小,则服务器上的唯一性标准将防止重复。
是的,这很好。Postgres甚至有UUID类型
如果客户端没有发送UUID,则将默认ID设置为由服务器生成的UUID
UUID旨在不发生碰撞。
避免使用UUIDv1,因为……
这涉及计算机的MAC地址和时间戳。请注意,此类UUID会显示创建标识符的计算机的身份和创建时间,这可能使其不适用于某些安全敏感的应用程序。 您可以使用uuid_generate_v1mc代替,它会隐藏MAC地址。 避免使用UUIDv3,因为它使用MD5。改用UUIDv5。 UUIDv4最简单,是一个122位的随机数,并内置于Postgres中(其他在常见的uuid-osp扩展中)。但是,它取决于每个客户端的随机数生成器的强度。但即使是糟糕的UUIDv4生成器也比递增整数好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接