0

代碼:BCrypt ::錯誤::在Rails的InvalidHash錯誤

class LoginController < ApplicationController 
    def auth 
     if params[:name].present? && params[:pass].present? && params[:role].present? 
       @name=params[:name] 
       pass=params[:pass] 
       role=params[:role] 

       epass = BCrypt::Password.new(pass) 
     else 
       render "argerror" 
     end 
    end 
end 

錯誤:

BCrypt::Errors::InvalidHash (invalid hash): 
app/controllers/login_controller.rb:12:in `new' 
app/controllers/login_controller.rb:12:in `auth' 

密碼加密機制:

salt = BCrypt::Engine.generate_salt 
pass = BCrypt::Engine.hash_secret(pass, salt) 

上面的代碼產品「BCrypt ::錯誤:: InvalidHash「錯誤。我的要求是從客戶端獲取用戶名和密碼,並使用存儲在數據庫中的數據驗證 。在數據庫中,我存儲了用bcrypt加密的用戶的散列密碼。所以,現在我試圖對 加密由客戶端輸入的密碼。加密當前密碼後,它與存儲在db中的散列密碼相匹配。但它會產生錯誤。如何解決這個問題呢 ?

回答

1

您需要給BCrypt::Password.new存儲在數據庫中的散列,而不是用戶提交的密碼。然後,將其與來自用戶的輸入進行比較。

例子:

# Create hash of password 
pass = BCrypt::Password.create('TestPassword') 
=> "$2a$10$3.D6D2htbiRrezmZUhePV.gaQlc3ZjFYD9hv43khN5eWP5y8BGUXG" 

# Pass the hash you have stored to Password.new 
db_hash = BCrypt::Password.new("$2a$10$3.D6D2htbiRrezmZUhePV.gaQlc3ZjFYD9hv43khN5eWP5y8BGUXG") 

# Compare the input from the user to the password stored 
db_hash == "TestPassword" 
=> true 

db_hash == "NotRealPassword" 
=> false 

您可以在這裏找到一些更多的信息:https://github.com/codahale/bcrypt-ruby#how-to-use-bcrypt-ruby-in-general

另外,如果你使用的Rails> = 3我會考慮使用ActiveModel::SecurePassword與您的用戶模型。一些更多的信息在這裏:http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html

+0

你能解釋它是如何驗證密碼。因爲,db有散列密碼,我們有明文密碼。我們只是將散列密碼傳遞給「BCrypt :: Password.new(user.password)」。我期望的是,我們需要獲取提交的密碼的哈希值,並使用該哈希值,我們可以檢查存儲在數據庫中的密碼以驗證用戶登錄憑據。但這裏有些不同。 – mrg

+0

當然。 'BCrypt :: Password.new(user.password)'有一個'=='的公共方法,所以當你調用'db_hash ==「plain_text」'它在引擎蓋下做的是加密你傳遞的純文本,然後比較哈希是否相同。 您可以在這裏看到'BCrypt'中的'=='的源代碼:http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009 我希望解釋 - 請讓我知道如果不。 – Kieran

+0

所以,這裏「==」不是我們在字符串比較中使用的相同的運算符。這樣對嗎 ? – mrg