Rails 6.0でアプリを開発 基本の流れ⑦ ログイン機能
アプリケーションにログインの機能を付ける際のメモ。セキュリティ上重要だと思うので基本ログイン機能はつけていきたい。
実現したいこと
ユーザーがログインできること。最終的に任意でログイン情報をブラウザに保存できること
認可モデルについて
ログイン情報はCookiesに保存する。認可の仕組みは下記の図を作ってみた
参考)rails tutorial 第8章
セッションのRESTfulなモデリング
new 新しいセッションを出力(ログイン)
create セッションを作り(cookiesへ)保存
destroy セッションを破棄(ログアウト)
①Sessionsコントローラを作成
$ rails g controller Sessions new
②ルーティングの設定
モデリングに合わせてルーティングを設定
③テストの編集
自動でできているSessions_controller_test.rbで名前付きルートを使うように編集
④ログインフォームを作成
セッションにはモデルがないのでユーザー登録フォームのように@usersのようなインスタンス変数がなく追加の情報は独自で渡す必要がある。
フォームのコードはこちら
⑤ログインフォームの送信を受けるcreateアクションを作成
1)emailからユーザーを見つける
2)ユーザーで勝つパスワードが有効ならtrue、どちらか違うならfalseに
3)ログイン
4)ログインできないときはログインフォームへ戻しエラー表示
flash.now→
レンダリングが終わっているページのみ(今回はログインフォーム)にメッセージを表示
⑥flashのメッセージを統合テストでテストする
$ rails g integration_test users_login
⑦Sessionヘルパーをどのコントローラーでも使えるようにする
セッションを実装するには、様々なコントローラやビューでおびただしい数のメソッドを定義する必要があります。Rubyのモジュール機能を使うと、そうしたメソッドを一箇所にパッケージ化できる(rails tutorial)
ApplicationコントローラーでSessionヘルパーモジュールを読み込む
⑧Sessions_helper.rbでメソッドをいろいろ作成していく
⑨log_inメソッドをcreateアクションに実装
ログイン後はユーザーのページにredirect_toで飛ばす
⑩レイアウトのリンクをログインによって変える
1)ログインをしているかどうかチェックするメソッドをsessions_helper.rbに追加
2)ヘッダーパーシャルでlogged_in?メソッドを使用して挙動を分ける
※注意※
ユーザーによってはプロフ画像を投稿しない場合があるのでその点も分岐
※併せてプロフ画像を使用しているshow.html.erbも編集
補足)ここでローカル環境で画像のチェックをしたときに出たエラーメモ
現象 ↓
画像を投稿しているユーザーのプロフページにログインした後、再度login画面をurl直打ちで表示した際、avatarがnilだと表示されエラーとなる
原因 ↓
ログアウト機能を設定していないので、/loginでurl直打ちをしたのだが、実はブラウザを閉じてなかったので、ログインをチェックしたユーザーのセッションがブラウザに残っておりログアウト扱いにならず、その状態でログインのページに移行しようとするとログインしている扱いになるのでエラーが出てしまっていた。
ある意味セッションメソッドが成功しているという形ではあるが少しはまった。
ブラウザの設定からcookieを削除した後、loginページのurlを直打ちすると正常に表示された
⑪レイアウト変更のテスト
レイアウト変更のテストのためにユーザーをログインさせるが、ユーザーログインの際にハッシュ化されたパスワードを使う。パスワードはhas_secure_passwordでbcryptを使用して作成されている。パスワード生成のコードは下記。
BCrypt::Password.create(string, cost: cost)
1)テストのコストパラメータを低くする
cost ↓
(コストパラメータ)ハッシュを計算するための計算コストを指定。高くすればハッシュから計算でオリジナルのパスワードを推測するのを困難にさせる。
テストはそこまで高いコストパラメータは必要ないので低くする
2)テストフィクスチャを作成
3)ユーザーログインのテスト
⑫ユーザー登録時にログインさせる
⑬テストで登録後ユーザーがログインするかどうかチェック
testで使用するのでtestヘルパーにログイン中かどうかをチェックするメソッドを作成
user_signupテストにメソッドを追加
⑭ユーザーをログアウトさせる
1)sessionヘルパーにlog_outメソッドを作る
2)sessions_controllerの中に実装
ログアウト後はトップページへリダイレクトさせる
3)ログインテストにログアウト部分も付け加える
今回はここまでだが、Bootstrapがあまり機能していないので訂正版に都度差し替えていきます。
ここでheroku にpush しようとするとエラーが発生
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/yourapp.git
原因はこれかな
Error: Cannot find module 'vue-loader'
vue-loaderはここに書いた。
bootstrapのレイアウトについては後で見直すとしてひとまずもとに戻しプッシュ
成功です。
参考にさせていただいたサイト
Rails 6にjQueryとBootstrapを入れる - Qiita
Railsでユーザー画像登録(デフォルト画像設定も含む)|Hiro|note