5

我正在尝试实现一种方法,以允许从设计之外的另一个服务更改密码。

# Profile password change
def change_password(oldpass, newpass)
    pepper  = nil
    cost    = 10

    # Encrypt plain text passwords
    encrypt_old     = ::BCrypt::Password.create("#{oldpass}#{pepper}", :cost => cost).to_s

    # Validate old
    if self.encrypted_password == encrypt_old
        encrypt_new     = ::BCrypt::Password.create("#{newpass}#{pepper}", :cost => cost).to_s
        self.encrypted_password = encrypt_new
        self.save
    else
        Logger.new("Wrong old password!")
    end
end

看来我的密码加密错误 oldpass 包含旧密码的纯文本,我需要对其进行哈希处理,看看它是否与当前密码匹配,然后允许存储新密码。但是,我得到的只是密码错误。

重做:

def change_password(oldpass, newpass)
    if valid_password?(oldpass)
        password = newpass
        save
        return true
    else
        return false
    end
end
4

2 回答 2

11

如果您在应用程序或 Rails 控制台中,则不需要自己加密密码。

只需按照以下方式更新用户,Devise 就会自行处理。

user.password = new_password
user.save

然后设计将加密密码并存储它。您只需要确保user.password_confirmationnil. 如果password_confirmation是其他任何东西,它将与password.

编辑

您可以通过以下方式检查现有密码:user.valid_password?(old_password)

于 2013-03-26T21:07:08.383 回答
3

使用 Devise,您无需自己处理使用 bcrypt。默认情况下,它处理这个和更改密码的方法。您可以在此处查看源代码,也可以config/intitalizers/devise.rb在您的 Rails 应用程序中查看。

另外,如果你使用#update_with_passwordDevise 提供的方法,那么你可以像这样传递一个哈希:

{ :current_password => 'pass', :password => 'pass_new', :password_confirmation => 'pass_new' }

或者,:password_confirmation如果您不希望用户必须提供确认,则可以省略。

编辑:我使用了错误的字段;它应该是“current_password”而不是“old_password”。

这是设计源中的相关方法:

  # Update record attributes when :current_password matches, otherwise returns
  # error on :current_password. It also automatically rejects :password and
  # :password_confirmation if they are blank.
  def update_with_password(params, *options)
    current_password = params.delete(:current_password)

    if params[:password].blank?
      params.delete(:password)
      params.delete(:password_confirmation) if params[:password_confirmation].blank?
    end

    result = if valid_password?(current_password)
      update_attributes(params, *options)
    else
      self.assign_attributes(params, *options)
      self.valid?
      self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
      false
    end

    clean_up_passwords
    result
  end

在 GitHub 上查看

于 2013-03-26T21:08:15.877 回答