Ala*_*man 19 ruby ruby-on-rails
我想在我的控制器中为"user_info_token"列中的用户生成一个令牌.但是,我想检查当前没有用户拥有该令牌.这段代码是否足够?
begin
@new_token = SecureRandom.urlsafe_base64
user = User.find_by_user_info_token(@new_token)
end while user != nil
@seller.user_info_token = @new_token
Run Code Online (Sandbox Code Playgroud)
或者有更清洁的方法来做到这一点?
yfe*_*lum 51
如果您的令牌是足够长的时间,并通过加密的安全[伪]随机数生成器生成的,那么你就不会需要验证令牌是独一无二的.你不会需要产生一个循环的令牌.
16个原始源字节足够长,可以有效保证.格式化URL安全性时,结果将更长.
# Base-64 (url-safe) encoded bytes, 22 characters long
SecureRandom.urlsafe_base64(16)
# Base-36 encoded bytes, naturally url-safe, ~25 characters long
SecureRandom.hex(16).to_i(16).to_s(36)
# Base-16 encoded bytes, naturally url-safe, 32 characters long
SecureRandom.hex(16)
Run Code Online (Sandbox Code Playgroud)
这是因为16字节或128位令牌不唯一的概率非常小,几乎为零.在大约2 64 = 18,446,744,073,709,551,616 = 1.845 x 10 19个代币生成后,只有50%的可能性有重复.如果你开始每秒产生10亿个代币,则需要大约2 64 /(10 9*3600*24*365.25)= 600 年,直到有50%的可能性发生任何重复.
但是你每秒钟不会产生10亿个令牌.让我们慷慨,假设你每秒产生一个令牌.即使一次碰撞有50%的可能性达到6000亿年的时间框架.在此之前,太阳已经被太阳吞噬了.
Dam*_*ien 33
我发现最干净的解决方案:
@seller.user_info_token = loop do
token = SecureRandom.urlsafe_base64
break token unless User.exists?(user_info_token: token)
end
Run Code Online (Sandbox Code Playgroud)
而且非常干净但有可能重复的东西(尽管很少):
@seller.user_info_token = SecureRandom.uuid
Run Code Online (Sandbox Code Playgroud)
编辑:当然,为您添加一个独特的索引:user_info_token.搜索具有相同令牌的用户将会快得多,并且如果偶然的话,会在同一时刻以完全相同的令牌保存2个用户,这将引发异常!
| 归档时间: |
|
| 查看次数: |
14197 次 |
| 最近记录: |