*devise使用:ログイン済みのユーザーのみをアクセス可能にする設定
遷移先へのボタンを隠すだけではダメ
大部分のアプリケーションでは会員登録機能がついており、登録してログイン済みでなければそのアプリのメイン機能を使用できないようになっているかと思います。
私が作成しているアプリでもログイン済みか否かによってナビバーの表示を変更し、ログイン済みでなければ先に進めないようにしてあります。
ログイン前↓
ログイン後↓
これはif文で分岐させることで実装できます。
deviseのヘルパーメソッドであるuser_signed_in?を用いてユーザーがログイン済みかどうかを判定します。
<% if user_signed_in? %> <li class="nav-item"> <%= link_to "#{current_user.username}さんのマイページ", user_path(current_user.id) %> </li> <li class="nav-item"> <%= link_to "助っ人を探す", maps_path %> </li> <li class="nav-item"> <%= link_to "チャット", "#" %> </li> <li class="nav-item"> <%= link_to "ログアウト", destroy_user_session_path, method: "delete" %> </li> <% else %> <li class="nav-item"> <%= link_to "会員登録", new_user_registration_path %> </li> <li class="nav-item"> <%= link_to "ログイン", new_user_session_path %> </li> <% end %>
未ログインではボタンそのものが無いのでアクセスできないと思いきや、
実はURLを直打ちすることで飛べてしまいます。
先程の私のアプリの例で、未ログインのまま "助っ人を探す" のページに飛んでみます!
直接URLを打ち込んでと。。。
飛べてしまいました。
添付画像の右上を見てもらえばわかりますが未ログインのままです。
対策をしましょう!!
before_actionで対策
当該のコントローラにおいてすべてのアクションで実行の前に共通の処理を行いたいときに、before_actionを使用すると全てのアクションが実行される前に指定したメソッドを呼び出すことができます。
つまり上記の例でいうと、
マップを表示させているmapsコントローラーはユーザーがログイン済みでないとアクションが実行されないように設定すれば良いのです。
app > controllers > maps_controller.rb
class MapsController < ApplicationController before_action :login_check # 省略 private def login_check unless user_signed_in? redirect_to root_path end end end
before_actionでlogin_checkというメソッドを定義します。
メソッドを書くのはprivate以下です。
上記のナビバーと同様にuser_signed_in?を使用します。
ユーザーがログインしてなければ "root_path"(TOPページ)にリダイレクトするようにしました。
これで未ログインのユーザーが直打ちで侵入することは防げました。
が、しかし・・・
もっと簡単な方法がありました。
deviseのヘルパーメソッドの一つに
before_action :authenticate_user!
があり、
app > controllers > maps_controller.rb
# authenticate_user!適用前 class MapsController < ApplicationController before_action :login_check # 省略 private def login_check unless user_signed_in? redirect_to root_path end end end #authenticate_user!適用後 class MapsController < ApplicationController before_action :authenticate_user! # 省略 end
上記のように1行で済みます!
会員登録にdeviseを使用していたら断然こっちですね!
ちなみに
デフォルトの設定ではログインしていない場合、ログイン画面に遷移する仕様になっています。
変更したい場合は下記のように上書きをすれば指定ページにリダイレクトされました。
app > controllers > maps_controller.rb
class MapsController < ApplicationController before_action :authenticate_user! # 省略 private def authenticate_user! redirect_to root_path end end