我发现签名全局ID是真棒基于令牌的东西一样重置密码和帐户确认功能,很想得到关于它的安全性和可用性的意见。除了使用设计的宝石验证令牌的签名全局ID - 安全还是易受攻击?
常用方式(模块可证实+可恢复)是
A)生成令牌(如d3f64ce7c125410498b5393b33e7cf3c
),将它们保存在数据库中,并发送链接/account_confirmation/#token#
B)的节能摘要这些令牌在数据库中,只发送邮件中的令牌 - 比较它们与BCrypt::Password.new(digest).is_password?(token)
。这个更安全的方法是Michael Hartl在他的Rails教程中使用的方法。
C.但是签名全局ID呢?
由于Rails 4.2中的Global ID Gem包含在Rails中,因此它被用于ActiveJobs。这就是我现在如何将它们用于例如帐户确认的东西:
包括GlobalID::Identification
您的用户模型比:
>> user_sgid = User.last.to_sgid(expires_in: 2.hours, for: 'confirmation')
=> #<SignedGlobalID:0x008fde45df8937
>> sgid_token = user_sgid.to_s
=> "BAhJIh5naWQ6Ly9pZGluYWlkaS9Vc2VyLzM5NTk5BjoGRVQ=--81d73[...]20e"
这个令牌,你可以通过电子邮件与帐户确认链接到你的用户,/account_confirmation/##sgid_token##
发送。
没有必要在数据库中保存account_confirmation_token
或其摘要。同时你并不需要保存account_confirmation_sent_at
时间戳来检查链接仍然是有效的 - 所有包含在sgid_token:
>> GlobalID::Locator.locate_signed(sgid_token, for: 'confirmation')
=> #<User:0x007fae94bf6298 @id="1">
# use the User model to activate the account, login, and so on
# 2 hours later if link expired:
>> GlobalID::Locator.locate_signed(sgid_token, for: 'confirmation')
=> nil
您可以发送不同的令牌多个环节,不同的到期时间和使用情况。我喜欢这种方法。
有关github上的gem描述的更多信息。
我的问题:
- 是签名全局ID令牌的安全或针对特定弱势攻击?
- 没有将令牌/摘要+ sent_at保存到数据库中的缺点?
- sgid_tokens起来达到200多个字符,所以链接变得很长,这个有什么问题吗?
- 为什么不使用签名的全局ID,但因此令牌/摘要的其他原因?
非常感谢您对此的看法!而且,对于每个GlobalID使用“for:'...'”选项来使用上下文是完全正确的,例如,我在'account_confirmation'和'reset_password'之间有所不同。当在数据库中存储摘要(而不是令牌)时,也不可能“查看”令牌 - 但是关于撤消的观点是一个好的观点......因此,我使用'expire_in'来确保链接a无效长 - 但完全撤销是不可能的。 – Steffen