iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0
自我挑戰組

Metaprogramming Ruby and Rails系列 第 21

Day 21 -- Rails BCrypt 使用者身分驗證

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

舉例來說:當使用者建立帳戶時所輸入的資訊
https://ithelp.ithome.com.tw/upload/images/20201006/201208686tw0zXYlUe.png

再來看看 log 發生了什麼事?
https://ithelp.ithome.com.tw/upload/images/20201006/20120868yVHMPkOxHE.png

注意看圖片內最後一行就是把密碼加密成為 “$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 來做加密和驗證功能。
設定上還蠻容易的,在 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)。
https://ithelp.ithome.com.tw/upload/images/20201006/20120868QSEgJYDSSE.png

接著我們可以來到 rails console 測試一下
https://ithelp.ithome.com.tw/upload/images/20201006/20120868SvehEvWjjI.png

從 rails console 可以看出,只有當authenticate拿到正確的密碼時,解密後才可以取得使用者 jeff 的資料了。

參考資料:
bcrypt-ruby
Authentication and Authorization à la Rails bcrypt
Rails 6 allows configurable attribute name on has_secure_password


上一篇
Day 20 -- Refinement Wrapper & Prepended Wrapper
下一篇
Day 22 -- Rails 快速實作使用者驗證機制
系列文
Metaprogramming Ruby and Rails33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言