[英]Can't authenticate on Rails with BCrypt - password hashes are different
我正在嘗試創建一個簡單的身份驗證系統,但似乎有問題。
注冊過程工作正常,但是當我嘗試使用完全相同的信息登錄時,我不能(我收到“無效的電子郵件或密碼”)。 如我所見,哈希比較返回false。 這是我的代碼:
#sessions_controller.rb
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
和
class User < ActiveRecord::Base
attr_accessor :password
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :name
validates_presence_of :email
validates_uniqueness_of :email
def self.authenticate(email, password)
user = User.where(email: email).first
# throw Exception.new(user.password_hash) #uncaught throw #<Exception: $2a$10$9FHhPyb7BW01ktwTTgZHX.hlKKv4ajX/dX9D/xNGmZoajJTdGG4N.>
# throw Exception.new(user.password_salt) #uncaught throw #<Exception: $2a$10$9FHhPyb7BW01ktwTTgZHX.>
# throw Exception.new(BCrypt::Engine.hash_secret(password, user.password_salt)) #uncaught throw #<Exception: $2a$10$9FHhPyb7BW01ktwTTgZHX.O62xalJit020Jb0g5XDdB5V8dGMslQS>
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
end
因此,正如您可以在user.rb的注釋行中看到的那樣,嘗試登錄時得到的密碼哈希與原始密碼不同。 顯然,我輸入的密碼是正確的。
user.password_hash = $2a$10$9FHhPyb7BW01ktwTTgZHX.hlKKv4ajX/dX9D/xNGmZoajJTdGG4N.
user.password_salt = $2a$10$9FHhPyb7BW01ktwTTgZHX.
BCrypt::Engine.hash_secret(password, user.password_salt) = $2a$10$9FHhPyb7BW01ktwTTgZHX.O62xalJit020Jb0g5XDdB5V8dGMslQS
你能在這里給我一個提示嗎? 我做錯了什么?
非常感謝!
//稍后編輯:還添加了用戶控制器,也許可以幫上忙。
class UsersController < ApplicationController
def new
@user = User.new(user_params)
end
def create
@user = User.new(user_params)
if @user.save
redirect_to root_url, :notice => "Signed up!"
else
render "new"
end
end
private
def user_params
params.fetch(:user).permit(:name, :email, :password, :password_confirmation) if params[:user]
end
end
編輯:發布用於注冊/登錄的日志
Started GET "/sign_up" for 127.0.0.1 at 2013-10-11 11:23:13 +0300
Processing by UsersController#new as HTML
Rendered users/new.html.erb within layouts/application (31.8ms)
Completed 200 OK in 48ms (Views: 41.8ms | ActiveRecord: 1.2ms)
Started POST "/users" for 127.0.0.1 at 2013-10-11 11:24:30 +0300
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LPLEs9at6BLGgjikYynnEzA/JAMMVl9IYGId1zEyNEg=", "user"=>{"name"=>"johntest", "email"=>"johntest@johntest.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create User"}
(0.1ms) BEGIN
User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'johntest@johntest.com' LIMIT 1
SQL (0.3ms) INSERT INTO `users` (`created_at`, `email`, `name`, `password_hash`, `password_salt`, `updated_at`) VALUES ('2013-10-11 08:24:30', 'johntest@johntest.com', 'johntest', '$2a$10$tpDFvkFUC.OPckDm6xacU.xkjFmECg2CDpsi3cjTJNX6K58ujHOn6', '$2a$10$tpDFvkFUC.OPckDm6xacU.', '2013-10-11 08:24:30')
(39.2ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 141ms (ActiveRecord: 40.0ms)
Started GET "/" for 127.0.0.1 at 2013-10-11 11:24:30 +0300
Processing by TroublesController#frontpage as HTML
Trouble Load (0.2ms) SELECT `troubles`.* FROM `troubles`
CACHE (0.0ms) SELECT `troubles`.* FROM `troubles`
Rendered troubles/_marker_infowindow.html.erb (0.8ms)
Rendered troubles/_marker_infowindow.html.erb (0.1ms)
Rendered /home/alex/.rvm/gems/ruby-2.0.0-p247/gems/gmaps4rails-1.5.6/app/views/gmaps4rails/_gmaps4rails.html.erb (1.9ms)
Rendered troubles/frontpage.html.erb within layouts/application (3.9ms)
Completed 200 OK in 21ms (Views: 13.5ms | ActiveRecord: 0.2ms)
[...](loading assets)
Started GET "/log_in" for 127.0.0.1 at 2013-10-11 11:24:52 +0300
Processing by SessionsController#new as HTML
Rendered sessions/new.html.erb within layouts/application (1.1ms)
Completed 200 OK in 14ms (Views: 12.8ms | ActiveRecord: 0.0ms)
Started POST "/sessions" for 127.0.0.1 at 2013-10-11 11:25:05 +0300
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LPLEs9at6BLGgjikYynnEzA/JAMMVl9IYGId1zEyNEg=", "name"=>"johntest", "email"=>"johntest@johntest.com", "password"=>"[FILTERED]", "commit"=>"Log in"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'johntest@johntest.com' ORDER BY `users`.`id` ASC LIMIT 1
Rendered sessions/new.html.erb within layouts/application (1.7ms)
Completed 200 OK in 99ms (Views: 10.9ms | ActiveRecord: 0.4ms)
[...](loading assets)
因此,我進入了注冊頁面,填寫了詳細信息,我被轉發到主頁,並顯示“ Signed up!”。 我單擊登錄,輸入詳細信息,並顯示“無效的電子郵件或密碼”。
Bcrypt正在以正確的方式解密,但是代碼中的罪魁禍首是before_save:encrypt_password只是將之前的保存事件更改為before_create事件。 使用before_save,每次更新用戶記錄時,都會調用一次crypto_password記錄,並且正在加密密碼字段,這樣您將丟失第一個加密密碼,盡管您提供了正確的密碼卻從未匹配過。 經過深入分析后,我陷入了同樣的問題,我知道了解決方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.