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

その後、Deviseはパスワードを暗号化して保存します。あなたはそれがであることを確認する必要がありuser.password_confirmationますnil。それ以外の場合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または、ユーザーが確認を提供する必要がない場合は省略できます。

編集:私は間違ったフィールドを使用しました。'old_password'ではなく'current_password'である必要があります。

Deviseのソースで問題となっている方法は次のとおりです。

  # 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 に答える