Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails RubyonRails——使用现有模式实现UUID作为主键_Ruby On Rails_Ruby_Postgresql_Uuid - Fatal编程技术网

Ruby on rails RubyonRails——使用现有模式实现UUID作为主键

Ruby on rails RubyonRails——使用现有模式实现UUID作为主键,ruby-on-rails,ruby,postgresql,uuid,Ruby On Rails,Ruby,Postgresql,Uuid,目前,我正在为一个移动应用程序创建一个RESTful API。RESTful API有许多端点,允许用户彼此交换个人信息。我正在测试这些端点的安全性,并很快意识到,如果第三方设法访问API,他们可以通过猜测用户id或使用自动脚本收集广泛的个人信息来轻松查找其他用户的信息。这是因为我使用的主键是一个简单的自动递增整数,这使得它可以预测并容易地确定其他用户的ID。我立即开始寻找一些不符合特定模式的东西。我遇到了UUID,并决定用我现有的rails应用程序实现它们 这是一个明智的决定吗?我肯定看到了使

目前,我正在为一个移动应用程序创建一个RESTful API。RESTful API有许多端点,允许用户彼此交换个人信息。我正在测试这些端点的安全性,并很快意识到,如果第三方设法访问API,他们可以通过猜测用户id或使用自动脚本收集广泛的个人信息来轻松查找其他用户的信息。这是因为我使用的主键是一个简单的自动递增整数,这使得它可以预测并容易地确定其他用户的ID。我立即开始寻找一些不符合特定模式的东西。我遇到了UUID,并决定用我现有的rails应用程序实现它们

这是一个明智的决定吗?我肯定看到了使用UUID的好处,但在进一步研究后,我发现这种方法有很多缺点。许多消息来源声称,使用UUID将导致大型表出现性能问题。UUID适合我的情况吗

我的第二个问题是关于在现有RubyonRails应用程序中实现这一点。我通过以下文章切换到UUID:。我在启用
uuid-ossp
扩展时遇到了一个问题。我创建了一个迁移,并将
enable_扩展'uuid ossp'
放在change函数中。然后,我更改了现有迁移以支持UUID作为主键,并运行
rake db:drop db:create db:migrate
以使用编辑的迁移重新创建数据库。此操作失败,错误为
PG::UndefinedFunction:error:函数uuid_generate_v4()不存在
。我很快意识到这是因为我创建了迁移,在我编辑了使用uuid的迁移之后启用了
uuid ossp
扩展。当我将迁移名称中的时间戳更改为所有迁移之前的日期时,
db:migrate
命令完成,没有错误。这让人感觉非常刻薄,挫败了迁移的目的。通过迁移添加此扩展的正确方法是什么

根据评论进行编辑:

因此,有很多评论建议,在允许用户查看某些数据之前,我应该正确地验证用户并检查他们的权限。我的应用程序中内置了用户身份验证功能,但可以更好地解释我的情况以及为什么我需要的不仅仅是自动递增的主键

我在这个应用程序上有很多用户,每个用户都可以创建私人和公共联系人。使用移动应用程序的每个人都可以查看公共联系人。私人联系人只能由创建它们的用户查看。但是,用户可以通过使用移动应用程序向其他用户显示二维码(QR code)与其他用户共享其私人联系人,二维码中编码了联系人ID。当用户解码联系人ID时,会向后端发送一个请求,通知后端用户现在是该私人联系人的所有者。这允许第二个用户现在从该私人联系人接收更新。这是我的应用程序的一大特点。这里的目的是迫使人们必须亲自交换这些联系人,并且不允许其他人看到这些联系人,除非这个过程已经发生

事实证明,实现这一概念相当棘手,因为所有用户都可能与系统上的任何其他用户共享所有私人联系人。我发现使用权限实现这一点非常困难,因为用户可以查看的联系人不断变化

最初,我使用自动递增的整数作为联系人ID的主键来实现它。它起作用了,但迫使我创建了一个非常不安全的API端点,该端点本质上将用户ID和私人联系人ID作为参数,并将该用户添加为该联系人的所有者。由于自动递增的ID是可预测的,因此具有API访问权限的用户可以在每次调用端点的数字序列中循环,将序列号作为联系人ID传入,并将自己添加为未与他们共享的联系人的所有者。这会让我不得不亲自分享联系人的整个过程变得简单,并且在很大程度上违背了拥有我的移动应用程序的目的

我决定我需要一些不太可预测的、完全随机的、对每个私人联系人来说都是独一无二的东西。我在研究解决这个问题时发现了UUID,并将模型中的联系人ID更改为UUID类型。UUID是解决这个问题的最佳方法吗?我应该用别的东西吗?我用错误的方法解决这个问题了吗

UUID是解决这个问题的最佳方法吗

你可以用它们作为解决方案。如果您这样做了,您应该构建一个新的联系人表和模型,而不是尝试迁移旧模型。除了很难实现之外,任何迁移都会立即使现有的联系人/邀请电子邮件无效(因为它们包含旧id)。简要地支持这两种模型,并在您对使用自动递增id模型的流量对应用程序不再重要感到满意后,停用旧的自动递增id模型

仍然存在一个缺陷-您的联系人共享链接现在将是持久的,如果任何人出于任何原因访问联系人的id,并且知道足够的信息来构建URL以获得该用户作为联系人,那么他们将能够向自己和完全不受您的应用程序控制的任何其他人共享该链接。这是因为您依赖于id的知识,这是阻止访问联系人详细信息的唯一因素

我应该用别的东西吗

在我看来,是的。使用单独的nonce或一次性代码模型(使用UUID,或包含长随机字符串的索引列-您可以使用
Sec