无法使用 Bcrypt 更新密码
Unable to update password with Bcrypt
我已经尝试了很多方法,但 BCrypt 似乎对用户提交的密码进行了两次加密。
当用户注册时 - Bcrypt 运行良好,我可以登录。但是当我尝试在 password_resets_controller 中更新他们的密码时,我无法再登录。我的数据库显示正在更新和散列密码,但我无法登录。
我什至删除了行 @customer.save
,但我的数据库仍然显示正在更新密码!
是否有我不知道的后台更新?请参阅相关的 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>
您可能正在分配 password
以及使用 password_hash
进行一些 post 处理。如果您拥有带有 password=
方法的模型代码,则打算使用它的方式是单独通过 password
。这意味着除了简单地分配它之外,您不需要做任何额外的工作。
你想要的 password_reset
方法是:
@customer.password = params[:password]
@customer.save!
应该通过适当的模型代码 运行 来处理它。
鉴于您的表单,新密码将在 params[:customer][:password]
而不是 params[:password]
- 您现有的代码总是将密码设置为 nil。
更改密码会将控制器更新操作重置为
@customer.password = params[:customer][:password]
应该可以解决问题。作为旁注,注释掉的 customer.save
无关紧要,因为您在下一行再次保存。
下次发生这种情况时,请考虑使用调试器来检查您的操作中发生了什么 - 很容易发现密码被设置为 nil。 debugging guide 对此有更多提示。
我已经尝试了很多方法,但 BCrypt 似乎对用户提交的密码进行了两次加密。
当用户注册时 - Bcrypt 运行良好,我可以登录。但是当我尝试在 password_resets_controller 中更新他们的密码时,我无法再登录。我的数据库显示正在更新和散列密码,但我无法登录。
我什至删除了行 @customer.save
,但我的数据库仍然显示正在更新密码!
是否有我不知道的后台更新?请参阅相关的 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>
您可能正在分配 password
以及使用 password_hash
进行一些 post 处理。如果您拥有带有 password=
方法的模型代码,则打算使用它的方式是单独通过 password
。这意味着除了简单地分配它之外,您不需要做任何额外的工作。
你想要的 password_reset
方法是:
@customer.password = params[:password]
@customer.save!
应该通过适当的模型代码 运行 来处理它。
鉴于您的表单,新密码将在 params[:customer][:password]
而不是 params[:password]
- 您现有的代码总是将密码设置为 nil。
更改密码会将控制器更新操作重置为
@customer.password = params[:customer][:password]
应该可以解决问题。作为旁注,注释掉的 customer.save
无关紧要,因为您在下一行再次保存。
下次发生这种情况时,请考虑使用调试器来检查您的操作中发生了什么 - 很容易发现密码被设置为 nil。 debugging guide 对此有更多提示。