Rails 小技巧 筆記簿:BCrypt 使用者身分驗證

王建豪
4 min readJan 29, 2020

前不久練習手刻 Rails 的會員系統,在建立使用者驗證機制時,通常我們會用 使用者名稱(Username), 電子信箱 (E-Mail) 及 密碼(Password) 來建立 User 表單。基於資安的保護,使用者在表單所填寫的密碼並不會直接儲存到資料庫內,而是先將密碼加密完成後的hash,再存到資料庫裡。

舉例來說:當使用者建立帳戶時所輸入的資訊

再來看看 log 發生了什麼事?

注意看圖片內最後一行就是把密碼加密成為 “$2a$12…zv706”後再存入資料庫裡,這其中的魔法就是 BCrypt gem 幫我們做的好事。BCrypt 提供 rails 開發者 has_secure_password 方法來做單向隨機加密及驗證在指定的password_digest欄位。順便一提,當使用 has_secure_password 方法時,會自動附帶3個驗證:1) 檢查密碼是否存在, 2) 密碼長度必須是不大於72 bytes, 3) 確認密碼填寫是否正確 (using a XXX_confirmation attribute)

貼心的 Rails 在 Gemfile 裡已有提供 BCrypt gem 來做加密和驗證功能。較詳細有關於 BCrypt加密演算法可參考文章:BCrypt 加密演算法精闢解釋

設定上還蠻容易的,在 user model 裡加上 has_secure_password 以及新增一個名為 password_digest的欄位在 users table 就可以有加密的效果了!

當需要驗證密碼時提供了authenticate的方法來做解密的動作。例如:user.authenticate('password')

這邊在使用 has_secure_password 時要注意使用的Rails版本。在 Rails 6.0 之前,has_secure_password 機制只接受一種屬性(attribute) 設定為 password_digest,因此表格的密碼欄位名稱都必須是password_digest。而在 Rails 6.0之後,has_secure_password允許可以自訂名稱的選項 ,也就是自訂欄位名稱+底線+digest (column_name_digest)。

接著我們可以來到 rails console 測試一下

--

--