【问题标题】:Using BCrypt in Rails to manually authenticate在 Rails 中使用 BCrypt 手动验证
【发布时间】:2014-07-24 20:58:34
【问题描述】:

我正在尝试在我的 rails 应用程序中使用 BCrypt 来安全地保存用户的密码。我能够很好地保存加密密码,甚至将其与原始纯文本字符串进行比较以成功验证它。问题似乎是,每次我加密密码时,我都会得到不同的输出(我假设是由于一些盐或其他原因),并且在保存到数据库后验证不成立(我保存在sqlite3 数据库,如果它有所作为)。

例如(在 Rails 控制台中):

2.1.2 :001 > u = User.new
 => #<User id: nil, created_at: nil, updated_at: nil, username: nil, password: nil> 
2.1.2 :002 > u.username = "jdoe"
 => "jdoe"
2.1.2 :002 > u.password = BCrypt::Password.create("snoopy")
 => "$2a$10$jJpHrgUmAh.YULY9CJUDjOSb9audpeD3Hx.66uVhix.WEDDB0HO.y" 
2.1.2 :003 > u.password == "snoopy"
 => true
2.1.2 :004 > u.save
 => true
u2 = User.find_by_username("jdoe")
 => [user "jdoe" is found here]
2.1.2 :006 > u2.password == "snoopy"
 => false

我知道有现成的解决方案,如 has_secure_password,但我想手动实现它以真正了解发生了什么。

【问题讨论】:

  • 您是否有理由不使用 Rails 内置的 has_secure_password,它使用 bcrypt? api.rubyonrails.org/classes/ActiveModel/SecurePassword/…
  • 我通常喜欢编写自己的方法(在合理的范围内),因此我对代码中发生的事情有深刻的理解。特别是如果它对我来说是新事物。一旦我觉得自己对技术有了充分的了解,我就会允许自己使用快捷方式或预先编写的代码。

标签: ruby-on-rails ruby bcrypt-ruby


【解决方案1】:

当您设置密码时,您将其设置为 BCrypt::Password 对象。我猜当你从数据库加载它时,它被加载为一个简单的字符串,所以== 不会用原始盐加密给定的字符串。

尝试以下方法:

(...)
u.save
u2 = User.find_by_username("jdoe")
BCrypt::Password.new(u2.password) == "snoopy"

编辑

Rails 似乎提供了一个after_find 回调,所以如果你定义这样的东西

class User < ActiveRecord::Base
  after_find do |user|
    user.password = BCrypt::Password.new(user.password)
  end
end

它应该按您的预期工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多