【发布时间】:2016-09-14 17:15:05
【问题描述】:
我发现 Signed Global IDs 对于重设密码和帐户确认功能等基于令牌的东西非常棒,我很想听听关于它的安全性和可用性。
除了使用 Devise gem(模块 Confirmable + Recoverable)之外的常用方法是
A) 生成令牌(例如d3f64ce7c125410498b5393b33e7cf3c),将它们保存在数据库中并将链接发送到/account_confirmation/#token#
B) 将这些令牌的摘要保存在 DB 中并仅在邮件中发送令牌 - 而不是将它们与 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 而是使用令牌/摘要的其他原因?
【问题讨论】:
标签: ruby-on-rails ruby security devise token