has_secure_passwordは簡単に言ったらユーザー登録やログインの時に出てくるパスワード入力に関するrailsのメソッドです。
has_secure_passwordを用いることで少ないコードでパスワードを安全に保管できるようにしてくれたり、ユーザー登録画面によくある、パスワード、確認パスワードなども作成できるようになります
今回はその__has_secure_password__についてしっかりまとめていきたいと思います。
##has_secure_passwordの使用方法
class User < ApplicationRecord
・
・省略
・
has_secure_password
end
##has_secure_passwordでできること
has_secure_passwordを用いると主に3つのことが可能になります
①セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
②2つのペアの仮想的な属性(passwordとpassword_confirmation)が使えるようになる。
③authenticateメソッドが使えるようになる(引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド)
###①セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
入力したパスワードをそのままデータベースに保存するのはセキュリティー上良くありません。
そのため__has_secure_password__を用いてハッシュ化といういわゆる暗号化を行い暗号化した状態でデータベースに保存します。
そしてログインするときなどにパスワードを入力すると思いますがそのパスワードもハッシュ化され、ハッシュ化されたパスワード同士を比べることでパスワードがあっているかどうかを確認します。
ハッシュ化にはさまざまなハッシュ関数が使われますが僕は__'bcrypt'__を使っています
下記のようにGemfileファイルに追加して使用します
gem 'bcrypt','3.1.13'
###②2つのペアの仮想的な属性(passwordとpassword_confirmation)が使えるようになる。
__has_secure_password__を使うには1つ条件があり、それはモデル内に__password_digest__という属性が含まれていることです。(password,password_confirmation属性はhas_secure_passwordを用いることで自動に仮想的に作成され、フォームにも利用できるのでモデルで明示的に作成する必要はありません)
例えば、ユーザー登録に名前、メールアドレス、パスワードが必要ならば下記のコードをコマンドに記述すれば良いです
rails generate model User name:string email:string password_digest:string
このようにモデルにpassword_digest属性を追加することによってhas_secure_passwordメソッドが使えるようになり、仮想的な属性(passwordとpassword_confirmation)もフォームで使えるようになります
以下に使用例を記述します
<%= form_with(model: @user, local: true) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
少し難しい記述はありますが、まず@userでユーザーモデルを元にフォームが作られていることがわかります。
そして、name,email,password, password_confirmationがフォームで使用されていることがわかります。
password_confirmationはモデルで明示的に記述していませんが、password_digestを追加することとhas_secure_passwordを記述することによって仮想的に作成され、使用できるようになっています
###③authenticateメソッドが使えるようになる
authenticateメソッドは非常に簡単で、authenticateメソッドの引数の文字列をハッシュ化した値と、データベース内にあるpassword_digestカラムの値を比較します。
その結果が同じならばTrue、違っていたらFalseを返します
>> User.create(name: "Michael Jordan", email: "Jordan@example.com",
?> password: "Michael", password_confirmation: "Michael")
>> user.authenticate("not_the_right_password")
false
>> user.authenticate("Michael")
True