A hashed password

安全密碼的機制由 Rails 的一個方法即能實現:has_secure_password

在 User model 裡面調用這個方法:

class User < ActiveRecord::Base
  .
  .
  .
  has_secure_password
end

調用這個方法後,會自動產生以下功能:

  • 在資料庫中的 password_digest 欄位儲存一組安全的 hashed value
  • 產生一組虛擬屬性(virtual attributes),passwordpassword_confirmation,也包含建立使用者物件時的 presence 驗證和匹配驗證
  • 獲得 authenticate 方法,如果密碼正確,會回傳使用者物件,反之回傳 false

虛擬屬性(virtual attributes)的意思是在 model 中有屬性,但資料庫裡沒有相對應的欄位。

要讓 has_secure_password 發揮作用的唯一條件就是,在 model 建立一個 password_digest 屬性(digest 這個字來自於 cryptographic hash functions 的術語。在這個情況下,hashed passwordpassword 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_digesthas_secure_password 方法使用最先進的 hash functionbcrypy。透過使用 bcrypt 加密密碼(hashing the password),可以確保駭客無法登入網站,就算他們設法取得資料庫的副本也一樣。

為了能使用 bcrypy,需要安裝 bcrypy gem:

source 'https://rubygems.org'

gem 'rails',                '4.2.2'
gem 'bcrypt',               '3.1.7'
.
.
.

執行 bundle

$ bundle install