Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.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 按用户创建唯一令牌时的表性能_Ruby On Rails - Fatal编程技术网

Ruby on rails 按用户创建唯一令牌时的表性能

Ruby on rails 按用户创建唯一令牌时的表性能,ruby-on-rails,Ruby On Rails,在我的用户模型中,我有以下方法: def confirmation_token self.confirmation = loop do random_token = SecureRandom.urlsafe_base64(16, false) break random_token unless User.exists?(confirmation: random_token) end end 此方法将只创建一个随机令牌来确认用户的电子邮件 正如您所

在我的用户模型中,我有以下方法:

def confirmation_token
    self.confirmation = loop do
        random_token = SecureRandom.urlsafe_base64(16, false)
        break random_token unless User.exists?(confirmation: random_token)
    end
end
此方法将只创建一个随机令牌来确认用户的电子邮件

正如您所看到的,它在User.exists?(确认:random_token)时循环,这意味着它将验证User表中是否已经没有类似的token

我的问题是:例如,如果我在“用户表”中有很多行,我需要在这个(确认)列中添加索引以提高性能


注意(此方法仅对每个用户执行一次…用户首次注册时)

是。如果您在任何特定列上进行多次搜索(在本例中为确认),则应为该列编制索引。

是。如果您在任何特定列上进行多次搜索(在本例中为确认),则应为该列编制索引。

如果您只是按该值搜索,则会给出简短的答案

尽管有些事情需要考虑。首先,您可能希望该索引是唯一的,随着表的增长,这将大大提高性能

add_index :users, :confirmation_token, unique: true
另外,您可能需要一个唯一的值,而不仅仅是随机值。虽然它不太可能生成重复,但它仍然是随机的,不是唯一的值。其中一个选项是从某个用户列生成和使用摘要类,您知道该列对于该表是唯一的,如下所示:

Digest::SHA1.hexdigest(user.email)
Digest::SHA1.hexdigest("#{user.email}-#{ENV['EMAIL_TOKEN_SECRET'}")
UPD:如果有人知道他使用电子邮件作为密钥并将其用于生成令牌,Asker会担心这种情况

这通常通过在加密之前向电子邮件添加一些唯一密钥来解决。您可以使用secure random生成这样的密钥,并将其存储在环境变量中。 在.bashrc/.profile/.bash_配置文件或您使用的任何其他配置文件中,执行以下操作:

export EMAIL_TOKEN_SECRET="M9SyIuuOPhakX0b6gjvcRnsRHY="
然后像这样做:

Digest::SHA1.hexdigest(user.email)
Digest::SHA1.hexdigest("#{user.email}-#{ENV['EMAIL_TOKEN_SECRET'}")

如果您只是通过该值进行搜索,则会给出简短的答案

尽管有些事情需要考虑。首先,您可能希望该索引是唯一的,随着表的增长,这将大大提高性能

add_index :users, :confirmation_token, unique: true
另外,您可能需要一个唯一的值,而不仅仅是随机值。虽然它不太可能生成重复,但它仍然是随机的,不是唯一的值。其中一个选项是从某个用户列生成和使用摘要类,您知道该列对于该表是唯一的,如下所示:

Digest::SHA1.hexdigest(user.email)
Digest::SHA1.hexdigest("#{user.email}-#{ENV['EMAIL_TOKEN_SECRET'}")
UPD:如果有人知道他使用电子邮件作为密钥并将其用于生成令牌,Asker会担心这种情况

这通常通过在加密之前向电子邮件添加一些唯一密钥来解决。您可以使用secure random生成这样的密钥,并将其存储在环境变量中。 在.bashrc/.profile/.bash_配置文件或您使用的任何其他配置文件中,执行以下操作:

export EMAIL_TOKEN_SECRET="M9SyIuuOPhakX0b6gjvcRnsRHY="
然后像这样做:

Digest::SHA1.hexdigest(user.email)
Digest::SHA1.hexdigest("#{user.email}-#{ENV['EMAIL_TOKEN_SECRET'}")

我需要在用户注册时创建一个确认令牌,如果您像这里一样验证唯一性。。。您可以看到,您需要一个方法来首先创建令牌!!所以:首先在验证之前创建令牌,然后验证列,最后在验证之后调用\u=3步而不是一步。。。不方便!!!明白了,我要把那一点去掉。我的答案应该仍然是你们需要的:添加一个索引。我需要在用户注册时创建一个确认令牌,如果你们像这里一样验证唯一性。。。您可以看到,您需要一个方法来首先创建令牌!!所以:首先在验证之前创建令牌,然后验证列,最后在验证之后调用\u=3步而不是一步。。。不方便!!!明白了,我要把那一点去掉。我的答案应该仍然是你所需要的:添加索引。我使用令牌进行电子邮件确认,因此如果我在用户的电子邮件中使用SHA1进行修复,这将成为一个安全问题,假设有人发现我在电子邮件地址中使用SHA1,他可以输入一封试探性的电子邮件,然后使用SHA1获取激活此电子邮件的链接,即使此电子邮件不存在…hi@Edgarsjekabson即使在您的更新答案中,问题仍然存在,如果您在您的秘密令牌中输入SHA1,您将获得以下信息:“b1dd3c7e24f7509d28ce865843eec5231b88cb23”->此加密值对于所有用户仍然相同:{用户电子邮件的加密值}-b1dd3c7e24f7509d28ce865843eec5231b88cb23,因此在用户电子邮件中执行SHA1很容易,然后将上面的值添加到其中:)我认为我的方法仍然是生成此类令牌的最佳方法。我不知道许多经验丰富的开发人员是否会同意依赖随机值生成唯一令牌,但选择权在你。如果有,这不是选择的问题一个安全的替代方案我将非常感激:)在主机上的您的环境中定义密钥/密码/访问令牌被认为是一个很好的方法。例如,Heroku和所有Heroku加载项都以这种方式提供凭据。如果有人能够看到这些值,您将受到威胁/被攻陷。我使用令牌r电子邮件确认,因此,如果我在用户的电子邮件中使用SHA1进行修复,这将成为一个安全问题,假设有人发现我在电子邮件地址中使用SHA1,他可以输入一封默认电子邮件,然后使用SHA1获取激活此电子邮件的链接,即使此电子邮件不存在……hi@Edgarsjekabson即使在您的更新中,问题仍然存在wer,如果您在您的秘密令牌中添加了SHA1,您将得到以下信息:“b1dd3c7e24f7509d28ce865843eec5231b88cb23”->此加密值对于所有用户仍然相同:{用户电子邮件的加密值}-b1dd3c7e24f7509d28ce865843eec5231b88cb23,因此在用户电子邮件中执行SHA1很容易,然后将上面的值添加到其中:)我认为我的方法仍然是生成此类令牌的最佳方法。我不知道许多经验丰富的开发人员是否会同意依赖随机值生成唯一令牌,但选择权在你。如果有,这不是选择的问题一个安全的替代方案我将非常感激:)在主机上的环境中定义密钥/密码/访问令牌被认为是一个很好的方法