2015-09-15 74 views
1

我發現密碼摘要在我的rails 4應用程序中無法正常工作 - 密碼摘要以明文形式存儲在數據庫中。使用rails4和use_secure_password以明文形式存儲密碼摘要

user.rb

class User < ActiveRecord::Base 
    has_secure_password 

    validates :password_digest, length: { minimum: 6 } 

end 

我的用戶數據庫遷移文件如下:

class CreateUsers < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.string :full_name 
     t.string :email 
     t.string :password_digest 

     t.timestamps null: false 
    end 
    end 
end 

任何想法我做錯了嗎?

編輯 我在Gemfile中bcrypt啓用(我跑了捆綁安裝)

gem 'bcrypt', '~> 3.1.7' 

當我嘗試在軌控制檯測試中,我得到一個無效的哈希錯誤:

2.2.1 :011 > user = User.new(full_name: 'abcd', email: '[email protected]', password_digest: 'abcdef') 
=> #<User id: nil, full_name: "abcd", email: "[email protected]", password_digest: "abcdef", created_at: nil, updated_at: nil> 
2.2.1 :012 > User.find_by(full_name: 'david').try(:authenticate, 'abcdef') 
    User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."full_name" = ? LIMIT 1 [["full_name", "david"]] 
BCrypt::Errors::InvalidHash: invalid hash 
     from /usr/local/rvm/gems/ruby-2.2.1/gems/bcrypt-3.1.10/lib/bcrypt/password.rb:60:in `initialize' 
     from /usr/local/rvm/gems/ruby-2.2.1/gems/activemodel-4.2.4/lib/active_model/secure_password.rb:102:in `new' 
     from /usr/local/rvm/gems/ruby-2.2.1/gems/activemodel-4.2.4/lib/active_model/secure_password.rb:102:in `authenticate' 
+0

您是否在您的Gemfile中啓用了'bcrypt' gem? –

+0

是 - gem'bcrypt','〜> 3.1.7' – user3813256

回答

2

這很奇怪,一切都應該起作用。嘗試從文檔一些例子在Rails控制檯:

user = User.new(name: 'david', password: '', password_confirmation: 'nomatch') 
user.save              # => false, password required 
user.password = 'mUc3m00RsqyRe' 
user.save              # => false, confirmation doesn't match 
user.password_confirmation = 'mUc3m00RsqyRe' 
user.save              # => true 
user.authenticate('notright')         # => false 
user.authenticate('mUc3m00RsqyRe')        # => user 
User.find_by(name: 'david').try(:authenticate, 'notright')  # => false 
User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user 

如果user.save回報false你可以看看user.errors爲驗證失敗的消息。

編輯:@madcow最後排序它的權利。現在,您需要將存儲在password_digest中的純文本密碼轉換爲bcrypt哈希值。

注意:您將無法使用此代碼恢復純文本密碼!如果您需要純文本密碼,請務必備份您的表格。

試試這個代碼爲單個用戶,並且,如果一切正常,這一技術應用到其他用戶:

user = User.find_by(name: 'david') 
user.password = user.password_confirmation = user.password_digest 
user.save! 

在這裏,我們分配給從user.password_digestuser.password您的明文密碼。由於has_secure_password重新定義了password=方法,因此您的純文本密碼應有效存儲回password_digest列,但現在作爲散列值。

要更新所有用戶:

User.find_each do |user| 
    user.password = user.password_confirmation = user.password_digest 
    user.save! 
end 
+0

我可以保存用戶 - 我可以在數據庫中看到它們。密碼字段是數據庫中的明文 – user3813256

+0

我收到了無效的哈希錯誤。更新後 – user3813256

+0

它會拋出錯誤,因爲你的'password_digest'不是有效的bcrypt散列。我有一種感覺,你已經在某處覆蓋了'User#password ='方法。它是否完成你在問題中顯示的用戶模型? –

2

你意外的密碼直接保存明文密碼消化領域,至少在控制檯的例子。這就是密碼存儲爲明文而不是散列的原因。

而是在控制檯輸入如此:

user = User.new(full_name: 'abcd', email: '[email protected]', password_digest: 'abcdef') 

輸入以下內容:

user = User.new(full_name: 'abcd', email: '[email protected]', password: 'abcdef', password_confirmation: 'abcdef') 
user.save 

然後找到用戶:

User.find_by(full_name: 'abcd').try(:authenticate, 'abcdef') 

不要直接設置:password_digest。始終通過:password:password_confirmation字段進行設置。

順便說一句,你正在得到那個無效的哈希錯誤,因爲它試圖解密你的明文(不是有效的哈希):password_digest的值。

+0

中保存pwd爲什麼密碼以明文形式保存以便開始?另外,我是否需要我的用戶數據庫遷移文件中的password_confirmation? – user3813256

+0

只是使用密碼而不是password_digest沒有給我一個錯誤 – user3813256

+0

這是正確的。不要直接設置'password_digest',你不應該得到一個錯誤。你不應該直接讀/設置它。該數據庫字段是'has_secure_password'的實現細節,應該保持封裝(隱藏)給我們的開發人員。 ;) – madcow

相關問題