2016-06-09 151 views
2

嗨即時通訊新的Bcrypt在軌道中,我想知道如何正確使用這個寶石,截至目前我能夠使密碼哈希,但是當它比較用戶輸入的密碼時不匹配。在軌道上加密紅寶石

這裏是我的加密和登錄代碼。

def self.login(user) 
    hashed_password = encrypt_password(user["password"]) 
    result = User.where({:username => user["username"], :password => hashed_password}) 
    return result 
end 

def self.add_user(user) 
    hashed_password = encrypt_password(user["password"]) 
    result = User.create({:username => user["username"], 
     :password => hashed_password, 
     :firstname => user["firstname"], 
     :middle_initial => user["middle_initial"], 
     :lastname => user["lastname"], 
     :advisory_class => user["advisory_class"]}) 
    return result 
end 

def self.encrypt_password(password) 
    password_salt = BCrypt::Engine.generate_salt 
    password_hash = BCrypt::Engine.hash_secret(password,password_salt) 
end 

在add_user中,我使用encrypt_password函數在使用登錄函數登錄時對其進行加密。密碼與數據庫中的密碼不匹配。我確定我沒有以正確的方式做這件事,你能否指出我在哪裏做錯了。謝謝。

+0

作爲說明,可以在形式爲'x({...})'的調用中省略散列花括號,因爲它們在Ruby中是隱含的。例如:'User.create(:username => user ['username'],...)'或甚至更好'User.create(username:user ['username'],...)'使用現代哈希符號。 – tadman

+0

謝謝你的提示,但那不是我現在主要關心的問題。 –

回答

4

這裏的訣竅是,BCrypt每次在設計中使用相同的密碼運行它時都會產生不同的結果。這使得該函數的輸出極其不可預測,所以對暴力猜測密碼是不實際的。

您驗證的方法是:

hashed_password = BCrypt::Password.create(user['password']) 

您驗證的方法是:

if @user = User.where(username: user['username']) 
    # User found 

    if BCrypt::Password.new(@user.password) == user['password'] 
    # Success! 
    else 
    # Invalid password 
    end 
else 
    # User not found 
end 

這工作,因爲==方法被覆蓋的密碼對象。它沒有做字面字符串比較。

+0

我已將我的登錄功能更改爲此。 \t DEF self.login(用戶) \t \t結果=假 \t \t hashed_pa​​ssword = ENCRYPT_PASSWORD(用戶[ 「密碼」]) \t \t用戶= User.where({:用戶名=>用戶[ 「用戶名」] }) \t \t如果BCrypt :: Password.new(hashed_pa​​ssword)==用戶[0]。密碼 \t \t \t結果=真 \t \t端 \t \t返回結果 \t結束 並給出無效散列的結果。那是什麼意思? –

+0

我不得不在這裏做一個編輯,因爲我混淆了'user'和'user'。 – tadman

+0

感謝您的幫助。那工作。 –