has_secure_password如何在我的模型类中工作?

时间:2013-03-20 03:38:36

标签: ruby-on-rails ruby ruby-on-rails-3

我正在做Rails tutorial by Michael Hartl,而且我已经到了你只需添加的地步:

has_secure_password

到你的模型类,发生了一堆魔法。

我知道这个方法来自ActiveModel::SecurePassword中包含的ActiveRecord::Base模块,我的模型类扩展了该模块。

我不明白当我将这一行添加到我的班级定义时会发生什么。有人可以尽可能详细地解释。我真的很想了解发生了什么,而不仅仅是在我的应用程序中抛出不知道它是如何工作的东西。

(如果它有助于理解为什么我感到困惑,我来自Java背景,我是Ruby的新手)

1 个答案:

答案 0 :(得分:9)

了解任何事情的最简单方法是咨询来源!在这种情况下,那将是ActiveModel::SecurePassword documentation。从那以后,您可以看到has_secure_password执行此操作:

def has_secure_password
  # Load bcrypt-ruby only when has_secure_password is used.
  # This is to avoid ActiveModel (and by extension the entire framework) being dependent on a binary library.
  gem 'bcrypt-ruby', '~> 3.0.0'
  require 'bcrypt'

  attr_reader :password

  validates_confirmation_of :password
  validates_presence_of     :password_digest

  include InstanceMethodsOnActivation

  if respond_to?(:attributes_protected_by_default)
    def self.attributes_protected_by_default
      super + ['password_digest']
    end
  end
end

用英语解释,这个功能:

  1. 加载bcrypt-ruby宝石,需要bcryptbcrypt是一种安全的散列函数,您可以在维基百科中了解更多信息。
  2. 向名为password的模型添加只读属性。
  3. 验证密码是否被另一个名为password_confirmation的字段确认。换句话说,您必须输入两次密码才能确认。
  4. 确保在保存模型之前存在password_digest。
  5. 加载instance methods,在这种情况下是authenticate(如果密码正确则返回true,否则返回false)和password=,它将传递的密码加密到password_digest属性中
  6. 如果方法具有默认受保护的属性,则还会将password_digest添加到受保护属性列表中。 (从而防止它被大规模分配。)
  7. 您可以在ActiveModel::SecurePassword documentationfurther documentation on its instance attributes了解详情。