deviseを使わないサインアップ/サインイン機能の実装
TECH::CAMPに通い始めてはや5ヶ月。
卒業までの期間も残すところあと1ヶ月となりました。
個人アプリ作成の合間の時間で作成している、就職活動用の個人アプリの作成において、
deviseを使わずにサインアップ・サインイン機能を実装してみようと思いました。
deviseは便利ですが、サインアップ・サインイン機能どういう仕組みで成り立っているのかがいまいちわかっていないため、
自分で実装してみよう!と思い立ちました。
参考にさせていただいた記事
https://qiita.com/tmzkysk/items/12c3392dff6da1c87fdf
https://qiita.com/d0ne1s/items/7c4d2be3f53e34a9dec7
テーブルとモデルを作成する
password_digestは、パスワードを暗号化するためのカラム名です。
必ずpasswordではなくpassword_digestとするようにしましょう。
次はモデルです。
保存する時にemailを全て小文字に変換します。
has_secure_password と記載(gem 'bcrypt'がインストールされていれば使えるメソッドです)することで、
・viewで:passwordと:password_confirmationという属性が使えるようになり、
パスワード入力・確認用の入力項目を作れるようになる。
password_confirmationはテーブルには保存されないため、
カラムがなくてもエラーは出ません。
・登録したパスワードを「password_digest」カラムに保存する際に
暗号化されるため、安全性が保たれる。
・authenticateメソッドが使えるようになる。
ログイン機能の実装の際に、
ユーザーが正しいパスワードを入力しているのかどうか判定できるメソッドです。
サインアップ・サインインページのマークアップとルーティング
サインイン時には、emailとパスワードの組み合わせが登録時のものと一致すれば、
サインインができるという仕組みです。
ルーティングはこのようにしています。
users: :new, :create → ユーザーの新規登録
users: :destroy → ユーザーの削除
sessions: :new, create → ログイン機能(セッションのスタート)
sessions: :destroy → ログアウト機能(セッションの終了)
コントローラーの作成
ここでdeviseでは使わない、session[:user_id]や、session[:user_name]が出てきました。
deviseではログインしているユーザーを「current_user」というメソッドで自動的に取得することができますが、
今回はcurrent_userが使えないため、
session[:user_id]などに、@userの持つ情報をそれぞれ代入しています。
(今回はビューで@userを使うので、userではなく@userにしています。)
次にサインイン時のコントローラー
SessionsControllerです。
サインインの仕組みとしては、
まず、入力したemailアドレスに一致するUserをuserに代入します。
そして
・userが存在すること(=入力したemailを持つUserが存在すること)
・userのもつpasswordが入力したpasswordと一致すること
以上の2つを満たすUserを探し当てることができれば、
session[:user_id]とsession[:user_name]に探し当てたuserの情報をそれぞれ代入します。
最後にroot_pathへ移動すれば、ログイン中のユーザー名をsession[:user_name]で表示させ、ログインできていることを確認します。
「3番」という名前のユーザーでログインしました。
しっかりユーザー名が表示されています!
まとめ
コードだけ見るとすごく簡単なのですが、
まず仕組みを理解するところからなので、これだけで1日かかってしまいました。
sessionの仕組みはPHPを触った時に少し学んだため、理解自体はそこまで時間が掛からなかったと思います。
一番引っかかったのは、コントローラーで
user.find_by(email: session_params[:email])とすることろです。
emailの値は「params」ではなく「session_params」に入っているのか!
と理解するまでに時間を要しました・・
次はサインインしているユーザー以外がアクセスできないようにするなど
バリデーションを加えて行きたいですが、
次回以降でアウトプットして行こうと思います。