无法使用Bcrypt更新密码

时间:2015-02-12 04:13:00

标签: ruby-on-rails ruby bcrypt

我尝试了很多方法,但似乎BCrypt正在加密用户提交的密码两次。

当用户注册时 - Bcrypt运行良好,我可以登录。但是当我尝试在我的password_resets_controller中更新他们的密码时,我再也无法登录了。我的数据库显示密码正在更新和散列,但我无法登录。

我甚至删除了行@customer.save,但我的数据库仍显示密码正在更新!

我不知道有什么东西正在更新吗?见relatd SO线程: Updating password with BCrypt

在我的Customer.rb

require 'bcrypt'
class Customer < ActiveRecord::Base
  include BCrypt

  def password
    @password ||= Password.new(password_hash)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end

  def self.authenticate(email, password)
    @customer = Customer.find_by_email(email)
    if @customer && @customer.password == password
      return @customer
    else
      return nil
    end
  end
end

在我的customer_controller中,实际运行的创建代码

  require 'bcrypt'
 class CustomersController < ApplicationController

  def create_customer_account_iphone
  @customer_count = Customer.where(email: params[:email]).size rescue nil
  if(@customer_count == 0 || @customer_count == nil ||)
    @customer = Customer.new(first_name: params[:first_name], email: params[:email])
    @customer.password = params[:password] //this calls my model methods
    @customer.save  //here I am saving
    unless (!@customer.save)
     respond_to do |format|
      msg = {:status => "SUCCESS", :messages => "Customer created", :data => @customer.as_json}
      format.json  { render :json => msg } # don't do msg.to_json
    end
  else
    respond_to do |format|
      msg = {:status => "FAILED", :messages => "Customer Not Saved"}
      format.json  { render :json => msg } # don't do msg.to_json
    end
  end


def sign_in_iphone
@customer = Customer.authenticate(params[:email], params[:password])
unless (@customer == 0 || @customer == nil)
  respond_to do |format|
    msg = {:status => "SUCCESS", :message => "CUSTOMER", :data => @customer.as_json}
    format.json  { render :json => msg } # don't do msg.to_json
  end
  else
    respond_to do |format|
      msg = {:status => "FAILED"}
      format.json  { render :json => msg } # don't do msg.to_json
    end
  end
end

在我的password_reset_controller

class CustomerPasswordResetsController < ApplicationController

   def edit
 @customer = Customer.find_by_password_reset_token!(params[:id])
end


def update
@customer = Customer.find_by_password_reset_token!(params[:id])
if @customer.password_reset_sent_at < 2.hours.ago
  redirect_to new_customer_password_reset_path, :alert => "Password  reset has expired."
else
  @customer.password_hash = BCrypt::Password.create(params[:password])
  # @customer.save
  unless !@customer.save
    redirect_to new_customer_password_reset_path, :alert => "Password has been reset!"
  else
    render :edit
  end
 end
end

在我的password_reset.html.erb

<%= form_for @customer, :url => customer_password_reset_path(params[:id]), :method => :patch  do |f| %>
<% if @customer.errors.any? %>
    <div class="error_messages">
      <h2>Form is invalid</h2>
      <ul>
        <% for message in @customer.errors.full_messages %>
            <li><%= message %></li>
        <% end %>
      </ul>
    </div>
<% end %>
<div class="field">
  <%= f.label :password %>
  <%= f.password_field :password %>
</div>
<div class="field">
  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit "Update Password" %></div>

2 个答案:

答案 0 :(得分:2)

根据您的表单,新密码将位于params[:customer][:password]而非params[:password] - 您现有的代码始终将密码设置为nil。

更改密码会重置控制器更新操作,而不是

 @customer.password = params[:customer][:password]

应该做的伎俩。作为旁注,注释掉customer.save并不重要,因为您再次保存在下一行。

下次出现这种情况时,请考虑使用调试器来检查操作中发生的情况 - 很容易发现密码设置为nil。 debugging guide对此有更多的提示。

答案 1 :(得分:1)

您可能正在分配password以及使用password_hash进行一些后处理。如果您拥有使用password方法的模型代码,那么打算使用它的方式仅通过password=。这意味着除了简单分配之外,您不需要做任何额外的工作。

您在password_reset方法中想要的是:

@customer.password = params[:password]
@customer.save!

这应该通过运行适当的模型代码来处理它。