###### tags: `Ruby on Rails 觀念` # Rails 該如何儲存隱私性密碼資料? 使用者在前台表單所填寫的密碼並不會直接儲存到資料庫內,而是先將密碼加密完成後的hash,再存到資料庫裡,加密的過程我們使用**密碼雜湊函式(one way hash digest)**,是因為它具有單向函式不可逆的特性,難以由一個已知的雜湊數值,去推算出原始的訊息。 ## 實作 Rails 內建方法 has_secure_password ### 一、new 一個新專案,建立初始 User Model 首先建立一個 User 的 model,初始裡面的欄位有 name 和 email ![](https://i.imgur.com/DP2oCGe.png) ### 二、在 Gemfile 安裝 BCrypt 開啟 Gemfile 做設定,在裡面寫入 bcrypt-ruby (~> 3.1.2),並執行`bundle install`安裝這個 gem,這個安裝的 **BCrypt** 就是 Rails 提供開發者做加密和驗證的便利功能。 ```rb= gem 'bcrypt-ruby', '~> 3.1.2' ``` ```shell= bundle install ``` 基本上 Rails 7 之後在 Gemfile 都已經預設 bcrypt 這個方法,只需取消註記後再 `bundle install`即可 ![](https://i.imgur.com/PJxQtG2.png) ### 三、新增 Migration 欄位 BCrypt 安裝完後,接下來在需要設置加密驗證的 model 裡加上 has_secure_password 方法以及 password_digest 的資料表欄位,就可以產生功能了 #### 1.新增一個 migration ,但不要急著 rails db:migrate ![](https://i.imgur.com/WhPVa5m.png) #### 2.先到 migration 裡加欄位,`add_column :users, :password_digest, :string` :users 要加密的資料表名稱 :password_digest 欄位名稱 :string 資料型別 ![](https://i.imgur.com/tFYhqNi.png) #### 3.確認新增欄位後,才 `rails db:migrate` ![](https://i.imgur.com/sAalZOY.png) #### 4.在 user.rb 新增 `has_secure_password` 方法 ![](https://i.imgur.com/kZDwbbO.png) ### 四、Rails console 測試一下 進入 `rails console` 環境 ```rb= shawn = User.new # User Model 建一個變數 shawn shawn.password = "railsOMG" # 僅當新密碼不為空時,才將密碼加密到password_digest屬性中 shawn.save # 存檔寫入記憶體 ``` ![](https://i.imgur.com/r0VNmjN.png) 在 development.sqlite3 查看 password_digest ![](https://i.imgur.com/Z4xCNsW.png) ## 參考 [Rails Digest 12 - has_secure_password](http://disco26.logdown.com/posts/175700-30-coder100-day-257-rails-digest-12-has-secure-password) [ActiveModel::SecurePassword::ClassMethods](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)