A hashed password
安全密碼的機制由 Rails 的一個方法即能實現:has_secure_password。
在 User model 裡面調用這個方法:
class User < ActiveRecord::Base
.
.
.
has_secure_password
end
調用這個方法後,會自動產生以下功能:
- 在資料庫中的
password_digest欄位儲存一組安全的 hashed value - 產生一組虛擬屬性(virtual attributes),
password和password_confirmation,也包含建立使用者物件時的 presence 驗證和匹配驗證 - 獲得
authenticate方法,如果密碼正確,會回傳使用者物件,反之回傳false
虛擬屬性(virtual attributes)的意思是在 model 中有屬性,但資料庫裡沒有相對應的欄位。
要讓 has_secure_password 發揮作用的唯一條件就是,在 model 建立一個 password_digest 屬性(digest 這個字來自於 cryptographic hash functions 的術語。在這個情況下,hashed password 和 password digest 是同一個意思。)
如下表:

所以現在來建立一個遷移檔案增加 password_digest 欄位:
$ rails generate migration add_password_digest_to_users password_digest:string
按照慣例,會在遷移檔案名稱後面加上 to_users,Rails 會自動建構一份增加欄位到 users 資料表的遷移檔案。password_digest 的類型是 string。
生成的遷移檔案如下:
db/migrate/[timestamp]_add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
執行遷移:
$ bundle exec rake db:migrate
為了製造 password_digest ,has_secure_password 方法使用最先進的 hash function :bcrypy。透過使用 bcrypt 加密密碼(hashing the password),可以確保駭客無法登入網站,就算他們設法取得資料庫的副本也一樣。
為了能使用 bcrypy,需要安裝 bcrypy gem:
source 'https://rubygems.org'
gem 'rails', '4.2.2'
gem 'bcrypt', '3.1.7'
.
.
.
執行 bundle
$ bundle install